Vishal Vishal - 9 months ago 27
AngularJS Question

watch function inside directive is not firing

I have a directive in angular as follows:

angular
.module('accountApp')
.directive('matchTo', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {

// var attributes = scope.$eval(attrs.matchTo);

ctrl.$validators.matchTo = function(modelValue) {

var attributes = scope.$eval(attrs.matchTo);

if(attributes.unequal == undefined) {
attributes.unequal = false;
}

console.log(modelValue);
console.log(attributes.matchString);
console.log(attributes.unequal);

if(attributes.unequal) {
if(attributes.matchString == undefined || attributes.matchString == null) {
return true;
} else {
return modelValue != attributes.matchString;
}
} else {
if(attributes.matchString == undefined || attributes.matchString == null) {
return false;
} else {
return modelValue == attributes.matchString;
}
}
}

scope.$watch(attrs.matchString, function() {
ctrl.$validate();
console.log('watch fired');
});

}
}
});


Here is my html:

<input type="text" id="name" name="name" class="form-control form-input" ng-model="creditDebit.name"
ng-disabled="isReadOnly" autocomplete="off"
required
ng-required-err-type="requiredCreditDebit" />

<input type="text" id="code" name="code" class="form-control form-input" ng-model="creditDebit.code"
ng-disabled="isReadOnly" autocomplete="off"
required
match-to="{ matchString: creditDebit.name, unequal: true}"
ng-required-err-type="requiredCreditDebitCode"
ng-matchTo-err-type="unMatchNameAndCode" />


Watch function fires only when page is reloaded. But I expect it to fire when value changes.

Answer Source

There is no need to watch attributes, because it's not attributes that changes, but rather matchString property on the scope. So I would do it like this:

var matchTo = $parse(attrs.matchTo);
scope.$watch(function () {
    return matchTo(scope).matchString;
}, function (value) {
    console.log(value);
});

See this plunker for details.