简体   繁体   English

从指令范围访问Angular工厂

[英]Access Angular Factory from Directive Scope

I'm pretty new to Angular, so maybe this isn't the best way to approach a problem. 我对Angular还是很陌生,所以也许这不是解决问题的最佳方法。 I'm trying to access a factory called Devices from a directive, called topDevices , scope. 我正在尝试从名为topDevices ,范围的指令访问名为Devices的工厂。

topDevices.js : 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'
    }
});

Is this something not normally allowed or just bad practice/approach? 这通常是不允许的,还是不好的做法/方法? Devices contains a list of devices using Devices.all() , but I also have a Devices.sortByKey(count, key) function to return a limited set of devices sorted by a particular key. Devices包含使用Devices.all()的设备列表,但我还有一个Devices.sortByKey(count, key)函数,用于返回按特定键排序的有限设备集。

EDIT: More info 编辑:更多信息

The purpose of this is to create a template that could list, for example, the top 5 devices by some X metric. 这样做的目的是创建一个模板,该模板可以按某些X指标列出例如前5名设备。 The template is this: 模板是这样的:

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

If this is an Angular factory you can pass it to the directive as a dependency: 如果这是Angular工厂,则可以将其作为依赖项传递给指令:

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

This way you are decoupling from the concrete instance you are using 这样,您就可以与正在使用的具体实例分离

If on the other hand you want to be able to pass the sortByKey() method, and use it in the isolated scope of the directive you should defined a scope property with '&' or '=' value. 另一方面,如果您希望能够传递sortByKey()方法,并在指令的隔离范围内使用它,则应使用“&”或“ =”值定义一个范围属性。

Using the ´=´ creates two way data binding, and it's the easiest to grasp: 使用´=´可以创建两种方式的数据绑定,并且最容易掌握:

 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);
    }

}); });

the link method of the directive is executed when it is created 指令的link方法在创建时执行
Then where you use the directive: 然后在使用指令的地方:

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

ctrl is the controller from the controllerAs syntax, you can attach the factory's method to the controller like ctrl是controller中的控制器作为语法,您可以将工厂方法附加到controller

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

I'll try to explain using the '&': 我将尝试使用'&'进行解释:

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
        });
    }

}); });

As you can see the function is called in a different way -> passing an object which keys are the arguments names and their corresponding values 如您所见,函数以不同的方式调用->传递一个对象,该对象的键是参数名称及其对应的值

Then where you use the directive: 然后在使用指令的地方:

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

Note that this is not calling the function, because we used the '&' property definition 请注意,这不是调用函数,因为我们使用了'&'属性定义

You can even use the sort function in the directive's html template: 您甚至可以在指令的html模板中使用sort函数:

topDevices.tpl.html topDevices.tpl.html

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

Not the brightest example but you get the point 不是最聪明的例子,但您明白了

Also you can check out this relevant answer 您也可以查看此相关答案

There is another way to pass the function like this 还有另一种传递函数的方式

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

Then in the ´link´ function you can use it like this 然后,在“链接”功能中,您可以像这样使用它

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

Small side note - in your example you cannot access ´this.count´ and ´this.sortKey´ in the place you are using them: 小注释-在您的示例中,您无法在使用它们的位置访问“ this.count”和“ this.sortKey”:
1. They are not yet defined. 1.它们尚未定义。 2. ´this´ doesn't refer the scope object. 2.“ this”未引用作用域对象。

Edit One way to achive you goal is by using a filter: check out this fiddle to see basic implementation. 编辑实现目标的一种方法是使用过滤器:查看此小提琴以查看基本实现。 Or maybe there is already a built in filter that can help you do this. 也许已经有一个内置的过滤器可以帮助您做到这一点。 Filters can be combined: 过滤器可以组合:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM