Reputation: 1894
A watch is not working. I ng-include the following content:
<form class="search">
<div class="searchbar">
<input type="search" value="" data-ng-model="searchKeyword" placeholder="zoeken">
<button type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</form>
like this:
<div ng-include src="filterPath" onload="initiateSearch()"></div>
The onload function is doing this:
(function(){
var appController = angular.module('ListerAppController', []);
appController.controller('ListerCtrl', ['$scope', '$rootScope', '$http', '$filter', '$timeout', '$sharedFactories', 'History', '$location',
function($scope, $rootScope, $http, $filter, $timeout, $sharedFactories, History, $location) {
$scope.initiateSearch = function () {
// This is what you will bind the filter to
$scope.filterText = '';
// Instantiate these variables outside the watch
var tempFilterText = '',
filterTextTimeout;
$scope.$watch('searchKeyword', function (val) {
if (filterTextTimeout) $timeout.cancel(filterTextTimeout);
tempFilterText = val;
filterTextTimeout = $timeout(function() {
$scope.filterText = tempFilterText;
$scope.pageCount = function() {
return Math.ceil( $scope.itemsfiltered.length / $scope.itemsPerPage );
};
}, 350); // delay 250 ms
});
};
}]);
})();
Everything seems to go allright but... the $watch on searchKeyword never fires the function when I start typing in the input element called searchKeyword.
Upvotes: 17
Views: 41153
Reputation: 2996
The simplest one is to pass true as the last argument of $watch.
For more reading:
https://github.com/mbenford/ngTagsInput/issues/174
Upvotes: 0
Reputation: 862
Just to add to the list of possible solutions:
While using forms:
Using ng-pattern will supress the call to $watch unless and until the input is validated by ng-pattern.
So just in case, if anyone is using ng-pattern, try $watch after removing ng-pattern.
For more reading:
Angular.js - ng-change not firing when ng-pattern is $invalid
Upvotes: 2
Reputation: 8447
Have you tried adding true
, as bellow?
$scope.$watch('searchKeyword', function (val) {
/* your logic here */
}, true);
If you're curious about what the true
is, here's the function signature from the docs:
$watch(watchExpression, listener, [objectEquality]);
When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications.
So apparently the significant thing is that it checks the equality of the old value and new value in a different way. I could see this being necessary if (correct me if I'm wrong) the value you're watching is, e.g., an array as opposed to a string.
Upvotes: 46
Reputation: 1258
The watch has to be an attribute of the object, not the object itself, see the example here https://docs.angularjs.org/api/ng/type/$rootScope.Scope on how to add a watch, and the use of the model here https://docs.angularjs.org/api/ng/directive/input. You could try this (I have not tested it)
data-ng-model="search.keyword"
and in your controller:
$scope.search = {}
...
$scope.$watch('search.keyword', ...
Upvotes: 39