简体   繁体   中英

AngularJS change in directive's scope not updating parent controller scope

HTML:

<div ng-app="myApp" ng-controller="Controller">
    <test ng-if="toggle" props="condition"></test>
</div>

Javascript:

var myApp = angular.module('myApp', []);

myApp.controller('Controller', ['$scope', '$timeout', function($scope, $timeout) {
    $scope.condition = [true];
    $scope.toggle = $scope.condition[0];
    $scope.$watch('condition', (newv, oldv, scope) => {
        console.log('old: ' + oldv);
        console.log('new: ' + newv);
        console.log('toggle: ' + scope.toggle);
    }, true);
}]);

myApp.directive("test", function() {
   return {
       template: '<div>directive show</div>',
       replace: true,
       scope: {
           props: "="
       },
       controller: ['$scope', '$timeout', function($scope, $timeout) {
           $scope.props[0] = false;
       }]
   }
});

The behavior is that after condition[0] is changed by directive to false, I can see the new value in console log, but toggle is not updating.

My question is :
Why toggle is not updating when condition[0] is changed? Why the digest cycle does not update toggle as well? Or does the digest cycle even update toggle at all when its assigned value changed?

And I am NOT asking for a solution to this problem but the cause of this problem.

Thanks!

Try to remove the replace: true in the directive's config.

when using replace: true , it will replace the directive tag with the content, so you will lose the ngIf directive as the initial value for toggle is true .

<test ng-if="toggle" props="condition"></test>

will be replaced with

 <div>directive show</div>

So the result will be

<div ng-app="myApp" ng-controller="Controller">
  <div>directive show</div>
</div>

To me, your question looks like this:

 var a = false; var b = a; console.log(a,b); var b = true; console.log(a,b);

Why is a not true after the second console.log ? Shouldn't a and b be the same?

No, because a and b are separate entities.

Similarly, when the code assigns the value false to $scope.props[0] in the directive's scope it is bound to $scope.condition[0] of the parent scope.

$scope.toggle and $scope.condition[0] are separate entities. a does not change when b changes.

$scope.toogle does not change when $scope.condition[0] changes.


Why the digest cycle does not update toggle as well? Or does the digest cycle even update toggle at all when its assigned value changed?

The ng-if="toggle" directive creates a watch on $scope.toggle . It never modifies $scope.toggle .

The props="condition" binding creates a watch on $scope.props of the directive and updates the value of $scope.condition of the parent $scope . Because it is a two-way binding, it also places a watch on $scope.condition of the parent and updates the $scope.props property of the directive.

The $scope.toggle property is never updated by the AngularJS framework or its digest cycle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM