简体   繁体   English

具有双向绑定,过滤和ng-repeat的Angular指令

[英]Angular directive with two way binding, filter and ng-repeat

I'm trying to create a directive that accepts an array of objects and run ng-repeat to render them. 我正在尝试创建一个接受对象数组并运行ng-repeat来呈现它们的指令。

app.directive("rockers", function(){
    return {
        restrict : "E",
        replace : true,
        scope : {
            items : '='
        },
        template : '<div>'+
                       '<span ng-repeat="item in items">{{item.name}} Rocks!</span>'+
                    '</div>'

    };
});

In the controller, I set the scope with opjects: 在控制器中,我使用opjects设置范围:

app.controller("appController", function($scope){
    $scope.scopedItems = [{name:"Aanny"}, {name:"Bonny"}, {name:"Danny"}];
});

And then, to call the directive I pass the scopedItems with filter, like this: 然后,为了调用指令,我使用过滤器传递scopedItems,如下所示:

<div ng-app="myApp" ng-controller="appController">
    Rockers: 
    <rockers items="scopedItems | filter:{name:'Bonny'}"></rockers>
</div>

Without using the filters in the HTML, everything works fine. 不使用HTML中的过滤器,一切正常。 When passing the filter I still get the results I want, but I'm also getting this error: " Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! " 通过过滤器时,我仍然得到我想要的结果,但我也得到了这个错误:“ 未捕获的错误:[$ rootScope:infdig] 10 $ digest()迭代到达。中止!

What am I doing wrong? 我究竟做错了什么?

Here is a jsFiddle link to recreate the error. 这是一个用于重新创建错误的jsFiddle链接

Thanks! 谢谢!

Also you can pass filtered data to directive like a string: 您也可以将过滤后的数据传递给指令,如字符串:

<rockers items="{{ scopedItems | filter:{name:'Bonny'} }}"></rockers>

and parse it value to object it directive: 并解析它的值以反对它的指令:

app.directive("rockers", function(){
    return {
        restrict : "E",
        replace : true,
        scope : {},
        link:function(scope, elem, attr){
            scope.items = JSON.parse(attr.items);
        },
        template : '<div>'+
                       '<span ng-repeat="item in items">{{item.name}} Rocks!</span>'+
                    '</div>'

    };
});

http://jsfiddle.net/34ag7/4/ http://jsfiddle.net/34ag7/4/

You can pass rocker name into directive by attribute and filter it there: 你可以通过属性将摇杆名称传递给指令并在那里过滤它:

<div ng-app="myApp" ng-controller="appController">
    Rockers: 
    <rockers name="Bonny" items="scopedItems"></rockers>
</div>

And in directive: 在指令中:

app.directive("rockers", function(){
    return {
        restrict : "E",
        replace : true,
        scope : {
            items : '='
        },
        link:function(scope, elem, attr){
            scope.filteredItems = function(filterItemName){
                return scope.items.filter(function(item){
                    return item.name == filterItemName;
                })
            };
            scope.filteredItem = scope.filteredItems(attr.name);
        },


        template : '<div>'+
                       '<span ng-repeat="item in filteredItem">{{item.name}} Rocks!</span>'+
                    '</div>'

    };
});

http://jsfiddle.net/b3dc9/39/ http://jsfiddle.net/b3dc9/39/

You could also use memoization in a custom filter to return the calculated value unless the input value changes. 除非输入值发生更改,否则您还可以在自定义过滤器中使用memoization来返回计算值。

See this example: Memoizing Angular filters to stop digest errors 请参阅此示例: 记住角度过滤器以停止摘要错误

I found a very simple solution involving adding another two-way bound scope variable to the directive and filtering inside the directive template instead of inside the html: 我发现了一个非常简单的解决方案,包括向指令添加另一个双向绑定范围变量,并在指令模板内部而不是在html内部进行过滤:

<div ng-app="myApp" ng-controller="appController">
    <input type="text" ng-model="find"><br>
    Rockers: 
    <rockers items="scopedItems" filter="find"></rockers>
</div>

Angular gives digest errors when a filtered array expression is passed in as a two-way bound directive scope variable. 当过滤后的数组表达式作为双向绑定指令范围变量传入时,Angular会产生摘要错误。 By using the filter attribute, you can filter anything you type in the input field, or use a $scope object to defined your filter eg $scope.find = {name: 'Bonny'}; 通过使用filter属性,您可以过滤在输入字段中键入的任何内容,或使用$ scope对象定义过滤器,例如$scope.find = {name: 'Bonny'}; You could even use a scope filter function or pre-defined filter, anything you would pass into a real filter expression will work because of the two-way binding. 您甚至可以使用范围过滤器函数或预定义过滤器,由于双向绑定,您传递到实际过滤器表达式的任何内容都将起作用。

var app = angular.module('myApp', []);

app.controller("appController", function($scope){
    $scope.scopedItems = [{name:"Aanny"}, {name:"Bonny"}, {name:"Danny"}];
});

app.directive("rockers", function($filter){
    return {
        restrict : "E",
        replace : true,
        scope : {
            items : '=',
            filter: '='
        },
        template : '<div>'+
                       '<span ng-repeat="item in items | filter:filter">{{item.name}} Rocks!</span>'+
                    '</div>'
    };
});

Working example: http://jsfiddle.net/2jhswna6/ 工作示例: http//jsfiddle.net/2jhswna6/

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

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