Angular Directive,Scope:True AND Add属性到范围

时间:2022-07-30 13:36:30

my directive is working fine, displaying all the trending tags. The directive looks for a trendingTag property in the $scope object. So I have scope: true

我的指令工作正常,显示所有趋势标签。该指令在$ scope对象中查找trendingTag属性。所以我有范围:真的

app.directive('ngTrending', function () {
    return {
        restrict: 'E'
        , transclude: true
        , replace: true
        , scope: true
        , templateUrl: '/resources/ngViews/trending.html'

    };
});

Now I want to be able to configure it based on options (like read-only="true") based on attribute on the directive. And be able to conditionally change minor aspects of the template based on the attirbute such tht

现在我希望能够根据指令的属性,根据选项(如read-only =“true”)对其进行配置。并且能够基于诸如此类的反对来有条件地改变模板的次要方面

<ng-trending></ng-trending>

Generates the trending tags with the actions enabled. While

在启用操作的情况下生成趋势标签。而

 <ng-trending read-only="true"></ng-trending>

generates the tags, but has the clicks disabled. How do I code the scope on the directive so that I still inherit the scope of the controller that is hosting the directive e.g.

生成标记,但禁用了点击次数。如何编写指令的范围,以便我仍然继承托管指令的控制器的范围,例如

<div ng-controller="fancy">
    <ng-trending></ng-trending>
</div>

as is the case now (inside of the template of the directive I reference the fancyContrllers $scope.trendingTags property). But inside of the directive's template I want to reference the "read-only" in the $scope.

就像现在的情况一样(在指令的模板内部我引用了fancyContrllers $ scope.trendingTags属性)。但是在指令模板中我想引用$ scope中的“只读”。

It just dawns on me that I am approaching this completely wrong, and that I probably want to pass the trending tags in as well... I am confused - please help straighten me out!

我刚刚意识到我正在接近这个完全错误,并且我可能也希望传递趋势标签......我很困惑 - 请帮助理顺我!

Thanks.

2 个解决方案

#1


1  

The normal procedure is to use an isolate scope to pass in any variables you want in directive (unless you need multiple directives on the element). This will result in a more reusable and testable directive, and clearer code as the directive won't be coupled to its surroundings.

正常的过程是使用隔离范围在指令中传入您想要的任何变量(除非您在元素上需要多个指令)。这将导致更可重复使用且可测试的指令,以及更清晰的代码,因为指令不会耦合到其周围环境。

For your case, if you write an isolate scope like this

对于您的情况,如果您编写这样的隔离范围

scope: {
    trendingTags: '=',
    readOnly: '='
    // ...
}

Then you can bind an expression on the outer scope to trendingTags on the inner scope, and the same with readOnly using attributes on the element.

然后,您可以将外部作用域上的表达式绑定到内部作用域上的trendingTags,并使用元素上的属性将readOnly绑定到相同的表达式。

You element would then look something like this

你的元素会看起来像这样

<ng-trending trending-tags="trendingTags" read-only="true"></ng-trending>

There is some more information on isolate scope here http://docs.angularjs.org/guide/directive.

有关隔离范围的更多信息,请访问http://docs.angularjs.org/guide/directive。

#2


1  

For completeness here is my working solution, including bindings for the actions. Any critiques are welcomed. Thank you andyrooger:

为了完整起见,这是我的工作解决方案,包括对操作的绑定。任何批评都受到欢迎。谢谢你andyrooger:

The directive:

app.directive('ngTrending', function () {
    return {
        restrict: 'E'
        , transclude: true
        , replace: true
        , scope: {
            trendingTags: '='
            , displayOnly: '='
            , inlineLabel: '='
            , filterTo: '&'
            , isFilteredTo: '&'
        }
        , templateUrl: '/resources/ngViews/trending.html'

    };
});

The template:

<div style="text-align: center">
    <div class="btn-group-xs">
        <span ng-show="(!!inlineLabel)" style="color: #81B1D9">Tagged: </span>
        <button ng-repeat="tag in trendingTags | orderBy:'count':true | limitTo:8" type="button" class="btn btn-default btn-primary"
                style="text-wrap: normal; margin: 2px;"
                ng-click="filterTo({filterToTag: tag.tagName})" ng-class="{active: isFilteredTo({filterToTag: tag.tagName}), disabled: (!!inlineLabel)}"><span
                ng-bind-html-unsafe="tag.tagName"></span> <span class="badge" ng-show="!(!!displayOnly)">{{ tag.count }}</span
        </button>
    </div>
    <button type="button" class="btn btn-xs btn-default" style="width: 150px; text-wrap: normal; margin-top: 3px"
            ng-click="filterTo({filterToTag: ''})" ng-show="!(!!displayOnly)">Clear
    </button>
</div>

In use:

 <ng-trending trending-tags="tags"
                    filter-to="filterTo(filterToTag)"
                    is-filtered-to="isFilteredTo(filterToTag)"></ng-trending>

#1


1  

The normal procedure is to use an isolate scope to pass in any variables you want in directive (unless you need multiple directives on the element). This will result in a more reusable and testable directive, and clearer code as the directive won't be coupled to its surroundings.

正常的过程是使用隔离范围在指令中传入您想要的任何变量(除非您在元素上需要多个指令)。这将导致更可重复使用且可测试的指令,以及更清晰的代码,因为指令不会耦合到其周围环境。

For your case, if you write an isolate scope like this

对于您的情况,如果您编写这样的隔离范围

scope: {
    trendingTags: '=',
    readOnly: '='
    // ...
}

Then you can bind an expression on the outer scope to trendingTags on the inner scope, and the same with readOnly using attributes on the element.

然后,您可以将外部作用域上的表达式绑定到内部作用域上的trendingTags,并使用元素上的属性将readOnly绑定到相同的表达式。

You element would then look something like this

你的元素会看起来像这样

<ng-trending trending-tags="trendingTags" read-only="true"></ng-trending>

There is some more information on isolate scope here http://docs.angularjs.org/guide/directive.

有关隔离范围的更多信息,请访问http://docs.angularjs.org/guide/directive。

#2


1  

For completeness here is my working solution, including bindings for the actions. Any critiques are welcomed. Thank you andyrooger:

为了完整起见,这是我的工作解决方案,包括对操作的绑定。任何批评都受到欢迎。谢谢你andyrooger:

The directive:

app.directive('ngTrending', function () {
    return {
        restrict: 'E'
        , transclude: true
        , replace: true
        , scope: {
            trendingTags: '='
            , displayOnly: '='
            , inlineLabel: '='
            , filterTo: '&'
            , isFilteredTo: '&'
        }
        , templateUrl: '/resources/ngViews/trending.html'

    };
});

The template:

<div style="text-align: center">
    <div class="btn-group-xs">
        <span ng-show="(!!inlineLabel)" style="color: #81B1D9">Tagged: </span>
        <button ng-repeat="tag in trendingTags | orderBy:'count':true | limitTo:8" type="button" class="btn btn-default btn-primary"
                style="text-wrap: normal; margin: 2px;"
                ng-click="filterTo({filterToTag: tag.tagName})" ng-class="{active: isFilteredTo({filterToTag: tag.tagName}), disabled: (!!inlineLabel)}"><span
                ng-bind-html-unsafe="tag.tagName"></span> <span class="badge" ng-show="!(!!displayOnly)">{{ tag.count }}</span
        </button>
    </div>
    <button type="button" class="btn btn-xs btn-default" style="width: 150px; text-wrap: normal; margin-top: 3px"
            ng-click="filterTo({filterToTag: ''})" ng-show="!(!!displayOnly)">Clear
    </button>
</div>

In use:

 <ng-trending trending-tags="tags"
                    filter-to="filterTo(filterToTag)"
                    is-filtered-to="isFilteredTo(filterToTag)"></ng-trending>