Reputation: 2773
I'm trying to launch a function everytime the ng-repeat is finished, I've got the following so far:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.friends = [{
name: 'John',
phone: '555-1276'
}, {
name: 'Mary',
phone: '800-BIG-MARY'
}, {
name: 'Mike',
phone: '555-4321'
}, {
name: 'Adam',
phone: '555-5678'
}, {
name: 'Julie',
phone: '555-8765'
}, {
name: 'Juliette',
phone: '555-5678'
}]
$scope.test = function() {
console.log('test');
}
});
app.directive('onFinishRender', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
scope.$evalAsync(attr.onFinishRender);
}
}
}
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="[email protected]" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<label>Search:
<input ng-model="searchText">
</label>
<table id="searchTextResults">
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
<tr ng-repeat="friend in friends | filter:searchText" on-finish-render="test()">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
</tr>
</table>
</body>
</html>
This fires the function once, but how would you modify this to make it work every time the filter get's applied?
Upvotes: 0
Views: 929
Reputation: 316
I have added scope to the directive. also ngRepeat's $last is sent through the scope variable. And changes to scope.last are being watched using scope.$watch so whenever list changes scope.last will change and then return true at the last step. This will run whenever there is a change in collection.
See the updated Plunkr
http://plnkr.co/edit/68XXIQyo2rkUP4uj6bnI?p=preview
HTML:
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="[email protected]" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<label>Search:
<input ng-model="searchText">
</label>
<table id="searchTextResults">
<tr>
<th>Name</th>
<th>Phone</th>
</tr>
<tr ng-repeat="friend in friends | filter:searchText" on-finish-render="test()" last="$last">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
</tr>
</table>
</body>
</html>
JS:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.friends = [{
name: 'John',
phone: '555-1276'
}, {
name: 'Mary',
phone: '800-BIG-MARY'
}, {
name: 'Mike',
phone: '555-4321'
}, {
name: 'Adam',
phone: '555-5678'
}, {
name: 'Julie',
phone: '555-8765'
}, {
name: 'Juliette',
phone: '555-5678'
}]
$scope.test = function() {
console.log('test');
}
});
app.directive('onFinishRender', function($timeout) {
return {
restrict: 'A',
scope: {
onFinishRender: '&',
last: '='
},
link: function(scope, element, attr) {
scope.$watch('last', function(){
if (scope.last === true) {
scope.onFinishRender();
}
});
}
}
});
Upvotes: 0
Reputation: 4711
If I understand your requirement correct, you would use ng-change directive to your input box of search.
Use this :
<input ng-model="searchText" ng-change="test();">
Upvotes: 1