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

时间:2014-04-03 09:43:41

标签: javascript angularjs angularjs-directive angularjs-ng-repeat

我试图创建一个接受对象数组并运行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>'

    };
});

在控制器中,我使用opjects设置范围:

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

然后,为了调用该指令,我使用过滤器传递scopedItems,如下所示:

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

不使用HTML中的过滤器,一切正常。通过过滤器后,我仍然可以得到我想要的结果,但我也收到了这个错误:&#34; 未捕获错误:[$ rootScope:infdig] 10 $ digest()迭代达到了。 !中止&#34;

我做错了什么?

这是一个jsFiddle link来重新创建错误。

谢谢!

4 个答案:

答案 0 :(得分:3)

您也可以将过滤后的数据传递给指令,如字符串:

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

并将其解析为对象指令:

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/

答案 1 :(得分:1)

你可以通过属性将摇杆名称传递给指令并在那里过滤它:

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

并在指令中:

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/

答案 2 :(得分:0)

除非输入值发生变化,否则您还可以在自定义过滤器中使用memoization来返回计算值。

请参阅此示例:Memoizing Angular filters to stop digest errors

答案 3 :(得分:0)

我找到了一个非常简单的解决方案,涉及向指令添加另一个双向绑定范围变量,并在指令模板内而不是在html内进行过滤:

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

当将过滤后的数组表达式作为双向绑定的指令范围变量传入时,Angular提供摘要错误。通过使用filter属性,您可以过滤在输入字段中键入的任何内容,或者使用$ scope对象定义过滤器,例如$scope.find = {name: 'Bonny'};您甚至可以使用范围过滤器功能或预定义的过滤器,由于双向绑定,传递给实际过滤器表达式的任何内容都将起作用。

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

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

相关问题