Using Angular 1.0.7:
I've a directive which is meant to display a styled checkbox.
See plunkr here.
Sometimes (and not always) my watcher doesnt update one of my scope's variable see:
Here is a failing sequence:
I wonder why the update doesnt occur.
It was very interesting question, so problem with combination of your clicked handler and preferences.email watch:
angularjs code:
//https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js line 4510
scope.$watch(function parentValueWatch() {
var parentValue = parentGet(parentScope);
if (parentValue !== scope[scopeName]) {
// we are out of sync and need to copy
if (parentValue !== lastValue) {
// parent changed and it has precedence
lastValue = scope[scopeName] = parentValue;
} else {
// if the parent can be assigned then do so
parentSet(parentScope, parentValue = lastValue = scope[scopeName]);
}
}
return parentValue;
});
break;
You are starting with click on foo + bar and we have:
all: true
foo: true
bar: true
Click by toggle all:
//by this code
var new_val = toggled_input_value();
$scope.model = new_val;
$scope.model is scope[scopeName] from the above code, so scope[scopeName] = false and lastValue = true, parentValue = true (they will be change after $digest run)
$scope.clicked({ value: new_val });
will call
$scope.toggleAll = function(new_value){
if (new_value){
$scope.preferences.email.foo = true;
$scope.preferences.email.bar = true;
}
else{
$scope.preferences.email.foo = false;
$scope.preferences.email.bar = false;
}
}
so,
all: true - $digest have not been run
foo: false
bar: false
and, begin $digest... first call will be:
$scope.$watch('preferences.email', function(new_value){
var bool = new_value.foo && new_value.bar;
$scope.preferences.all = bool;
}, true);
so,
all: false
foo: false
bar: false
it's a problem, because on the next parentValueWatch call we'll get:
parentValue = false //$scope.preferences.all
scope[scopeName] = false //$scope.model
lastValue = true
so, parentValue === scope[scopeName], and lastValue have not been updated... it's a bug:)
when you will change $scope.preferences.all to the true, you will get
$scope.preferences.all === lastValue //true
and call
// if the parent can be assigned then do so
parentSet(parentScope, parentValue = lastValue = scope[scopeName]);
so, $scope.preferences.all will become false, instead of a true
you can look at this here http://plnkr.co/edit/YEHqA101YwWKDvK6odFf?p=preview (console.trace)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With