【问题标题】:Angular Directive, Scope: True AND Add attribute to scope角度指令,范围:True AND 将属性添加到范围
【发布时间】:2013-10-14 19:22:25
【问题描述】:

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

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

    };
});

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

<ng-trending></ng-trending>

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

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

生成标签,但禁用点击。如何对指令的范围进行编码,以便我仍然继承托管指令的控制器的范围,例如

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

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

我突然意识到我完全错误地处理了这个问题,并且我可能也想传递趋势标签......我很困惑 - 请帮助我理顺我!

谢谢。

【问题讨论】:

  • 如果您不想更改指令的范围,我认为您可以检查 link 函数中的属性(attrs.readOnly 会给您一个字符串值)。您可以使用scope.$eval(attrs.readOnly)$parse 进行单向和双向绑定。
  • @jpmorin 的建议对我很有效。尽管在某些情况下它可能很有效,但这并不是要养成的习惯。

标签: javascript angularjs


【解决方案1】:

正常的过程是使用隔离作用域在指令中传递您想要的任何变量(除非您需要在元素上使用多个指令)。这将产生一个更可重用和可测试的指令,以及更清晰的代码,因为指令不会与其周围环境耦合。

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

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

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

你的元素看起来像这样

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

这里有更多关于隔离范围的信息http://docs.angularjs.org/guide/directive

【讨论】:

  • 如果属性上没有定义,那么scope.readOnly 将是undefined。您可以对此进行测试并根据需要使用默认值。或者,您可以只使用scope.readOnly 本身,当未定义时您只需要“虚假”的东西......或者!!scope.readOnly 将强制转换为布尔值。
【解决方案2】:

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

指令:

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

    };
});

模板:

<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>

使用中:

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

【讨论】:

    猜你喜欢
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    相关资源
    最近更新 更多