具有过滤器属性的Angular自定义指令

时间:2013-06-07 02:14:02

标签: angularjs angularjs-directive angularjs-filter

我想使用angular指令,我在数据上使用filter作为参数传递。

这样的事情:

<div class="my-module" data="a in array | orFilter:filter"></div>

其中“data”是指令“my-module”的属性。 我查看了ngRepeat源代码,但是他们解析了ng-repeat参数,然后对它们进行了评估。我不能使用ng-repeat,因为我正在从数据参数创建新的对象实例(地图标记)。

这真的很难吗?可以在自定义指令中执行此操作吗?

我想要的小例子:http://jsfiddle.net/PjRAr/1/

修改

我正在尝试扩展此map wrapper以呈现已过滤的标记。

我的潜力解决方案是保留所有标记和可见标记的副本。添加$ watch进行过滤,更改过滤器时调用$scope.markers = $scope.$eval("allMarkers | orFilter:filter");

使用此解决方案,我们需要保留所有标记的两个副本(~500)。

3 个答案:

答案 0 :(得分:3)

您可以$eval过滤器表达式。

在你的指令链接函数中:

elem.text( scope.$eval( attrs.data ).join(', ') );

在你的模板中:

<div my-directive data="['Hello', 'xxx', 'World'] | filter:'o'"></div>

并且指令呈现(通过过滤'xxx')到:

Hello, World

编辑

如果值是动态的,您当然可以这样做:

scope.$watch( attrs.data, function( arr ) {
  elem.text( arr.join(', ') );
});

但我认为你不能避免$watch

答案 1 :(得分:0)

我认为你混合了一些东西。我不确定你为什么不想使用ng-repeat,这就是它的用途。因为您隔离了范围,所以您无权访问父范围。 '='绑定尝试将您的隔离范围数据属性绑定到父范围的模型,该模型称为属性中的内容,但您无法绑定到已过滤的内容。如果您不想使用属性重复div,请将它们放在您自己的元素上,它只是创建内容......

这是一个显示使用ng-repeat的小提琴。您可以看到绑定是双向的,它会添加updated: true属性。

(FIDDLE)

    link: function (scope, element, attrs, ctrl) {
        element.append('<p>a: ' + scope.data.a + ', b: ' + scope.data.b);
        scope.data.updated = true;
    }

答案 2 :(得分:0)

所以,当我使用单向绑定时,我在$ watch中获得了空数组(我认为它正在尝试在本地范围内进行评估[从单向绑定的指令范围中删除“数据”]。当我使用双向绑定时[在指令范围是{data:“= data”}]我得到错误“看守在最后5次迭代中被解雇”(这是以角度过滤的常见错误)。

所以我的解决方案:

指令:

...
scope: {
  data: "=data"
}
...
link: function (scope, element, attrs, ctrl) {
  ...
  scope.$watch("data", function (newValue) {
    angular.forEach(newValue, function (v, i) {
      model.add(v);
    }
  }
}
...

控制器:

  ...
  $scope.filter = { a:true, b:false, ... };
  $scope.all = [..data..];
  $scope.visible = [..data..];    

  $scope.$watch("filter", function(newValue) {    
    $scope.visible = $scope.$eval("all | orFilter:filter"); 
  }, true);
  ...

HTML:

<div my-module data="visible"></div>

非常感谢你们,你们这么帮助我。我学到了很多关于角度绑定的新东西。