具有双向绑定、过滤器和 ng 重复的角度指令

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

本文关键字:指令 ng 绑定 过滤器      更新时间:2023-09-26

我正在尝试创建一个接受对象数组并运行 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>'
    };
});

在控制器中,我用反对设置范围:

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中的过滤器,一切正常。通过过滤器时,我仍然得到我想要的结果,但我也收到此错误:"未捕获错误:[$rootScope:infdig] 达到 10 次 $digest() 次迭代。流产!

我做错了什么?

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

谢谢!

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

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

您可以按属性将摇杆名称传递到指令中并在那里过滤它:

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

您还可以在

自定义筛选器中使用记忆来返回计算值,除非输入值发生更改。

请参阅此示例:记忆角度滤波器以阻止摘要错误

我找到了一个非常简单的解决方案,涉及向指令添加另一个双向绑定范围变量并在指令模板内而不是在 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/