Angular custom directive with filter in attribute
Solution 1
So, when I use one-way binding i got empty array in $watch (i think it's trying evaluate in local scope [removed "data" from directive scope for one way binding]. When i use two way binding [in directive scope is {data: "=data"}] i got error "Watchers fired in the last 5 iterations" (it's common error for filtering in angular).
So my solution:
Directive:
...
scope: {
data: "=data"
}
...
link: function (scope, element, attrs, ctrl) {
...
scope.$watch("data", function (newValue) {
angular.forEach(newValue, function (v, i) {
model.add(v);
}
}
}
...
Controller:
...
$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>
Thank you very much guys, you're help me so much. I'm learned many new things about angular binding.
Solution 2
You can $eval
the filter expression.
in your directive link function:
elem.text( scope.$eval( attrs.data ).join(', ') );
in your template:
<div my-directive data="['Hello', 'xxx', 'World'] | filter:'o'"></div>
and the directive renders (by filtering-out 'xxx') to:
Hello, World
EDIT:
If the values are dynamic, you can of course do:
scope.$watch( attrs.data, function( arr ) {
elem.text( arr.join(', ') );
});
I do not think you can avoid having $watch
, though.
Petr B.
Updated on June 04, 2022Comments
-
Petr B. almost 2 years
I would like make angular directive where I use filter on data which are passed as argument.
So something like this:
<div class="my-module" data="a in array | orFilter:filter"></div>
Where "data" is attribute of directive "my-module". I looked into ngRepeat source, but they parse ng-repeat argument and then they evaluate them. I can't use ng-repeat because I'm creating new instance of object (Marker for map) from data parameter.
Is it realy so hard? Is possible do this in custom directive and how?
Small example what i want: http://jsfiddle.net/PjRAr/1/
EDIT
I'm trying extend this map wrapper to render filtered markers.
My potencional solution is holding copy of all markers and visible markers. Add $watch to filter and when filter was changed call
$scope.markers = $scope.$eval("allMarkers | orFilter:filter");
.With this solution we need hold two copy of all markers (~500).