【问题标题】:Access Angular Factory from Directive Scope从指令范围访问 Angular 工厂
【发布时间】:2016-08-21 21:09:58
【问题描述】:

我对 Angular 还是很陌生,所以也许这不是解决问题的最佳方法。我正在尝试从名为 topDevices 的指令范围内访问名为 Devices 的工厂。

topDevices.js:

app.directive('topDevices', function() {
    return {
        restrict: 'E',
        scope: {
            count: '@',
            sortKey: '@',
            devices: Devices.sortByKey(this.count, this.sortKey)
        },
        templateUrl: 'app/directives/topDevices.tpl.html'
    }
});

这是通常不允许的事情还是只是不好的做法/方法? Devices 包含使用 Devices.all() 的设备列表,但我还有一个 Devices.sortByKey(count, key) 函数来返回按特定键排序的有限设备集。

编辑:更多信息

这样做的目的是创建一个模板,例如,可以按某个 X 指标列出前 5 个设备。模板是这样的:

<h3>Top {{ count }} by {{ sortKey }}</h3>
    <table class="table table-bordered table-condensed table-striped table-hover">
        <tbody>
            <tr ng-repeat="device in devices">
                <td>{{ device.id }}</td>
                <td>{{ device.name }}</td>
                <td>{{ device[sortKey] }}</td>
            </tr>
            <tr ng-show="!devices.length">
                <td colspan="3">No device info available</td>
            </tr>
        </tbody>
    </table>

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    如果这是一个 Angular 工厂,您可以将其作为依赖项传递给指令:

    app.directive('topDevices', function(Devices) {...})
    

    这样你就可以从你正在使用的具体实例中解耦

    另一方面,如果您希望能够传递 sortByKey() 方法,并在指令的隔离范围内使用它,则应使用 '&' 或 '=' 值定义范围属性。

    使用 ´=´ 创建两种方式的数据绑定,这是最容易掌握的:

     app.directive('topDevices', function() {
      return { 
        restrict: 'E', 
        scope: { 
            count: '@', 
            sortKey: '@',
            sort: '='
         }, 
    
        templateUrl: 'app/directives/topDevices.tpl.html'
         },
        link: function(scope) {
            scope.sort(scope.count, scope.sortKey);
        }
    

    });

    指令的link 方法在创建时执行
    然后在哪里使用指令:

    <top-devices sort="ctrl.sortByKey"></top-devices>
    

    ctrl是controller中的controllerAs语法,你可以像这样将工厂的方法附加到控制器上

    // inside a controller
    this.sortByKey = function(count, sortKey) {
         return Device.sortByKey(count, sortKey);
     } 
    

    我将尝试使用“&”来解释:

    app.directive('topDevices', function() {
    return { 
        restrict: 'E', 
        scope: { 
            count: '@', 
            sortKey: '@',
            sort: '&'
         }, 
    
        templateUrl: 'app/directives/topDevices.tpl.html'
         },
        link: function(scope) {
            scope.sort({
                count: scope.count,     
                sortKey: scope.sortKey
            });
        }
    

    });

    如您所见,函数以不同的方式调用 -> 传递一个对象,其中键是参数名称及其对应的值

    然后你在哪里使用指令:

    <top-devices sort="ctrl.sortByKey( count, sortKey)"></top-devices>
    

    注意这不是调用函数,因为我们使用了'&'属性定义

    您甚至可以在指令的 html 模板中使用排序功能:

    topDevices.tpl.html

    <div ng-show="sort({count: count, sortKey: sortKey})">
        <a href="#" ng-repeat...>{{something}}</a>
    </div>
    

    不是最聪明的例子,但你明白了

    您也可以查看this relevant answer

    还有另一种方法可以像这样传递函数

    <top-devices sort="ctrl.sortByKey"></top-devices>
    

    然后在“链接”功能中,您可以像这样使用它

    {
         ...
        link: function(scope) {
             var unwrapped = scope.sort();
             unwrapped( scope.count, scope.sortKey); 
        }
    }
    

    附带说明 - 在您的示例中,您无法在使用它们的地方访问“this.count”和“this.sortKey”:
    1. 尚未定义。 2. 'this' 不指范围对象。

    编辑 实现目标的一种方法是使用过滤器: 查看this fiddle 以查看基本实现。 或者也许已经有一个内置的过滤器可以帮助你做到这一点。 过滤器可以组合:

    <li ng-repeat="data in collection | filter1:arg | filter2:bar | filter1:foo></li>
    

    【讨论】:

    • 嗨,我的钱:你可以通过调用它的方法 réf inteed ==> ""
    • 当使用 '&' 时,你必须像这样引用它 -> 它没有调用方法
    • 非常感谢您的详细解释。我仍然很难掌握这一切,但这主要是因为我对 Angular 还很陌生。我想我能做的就是调用&lt;top-devices count="5" sort-key="keyName"&gt;&lt;/top-devices&gt;,然后就能够呈现按keyName 的值排序的前5 个设备。从您提供的示例中,控制器和指令之间似乎涉及更多的耦合,我什至不确定如果 countsortKey 未列出,我是如何将它们传递到指令中的作为&lt;top-devices&gt;&lt;/top-devices&gt; 的属性。
    • 很高兴我能提供帮助,从附加信息来看,您似乎只需要一个过滤器。在底部查看我的编辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    相关资源
    最近更新 更多