{{...">

Angular does not update associated property

Fiddle

HTML:

<div ng-controller="MyCtrl">
    <button my-event-directive>Click me</button>
    <div>{{secret}}</div>
</div>

      

JS:

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

myApp.directive('myEventDirective', function() {
      return {
        link: function(scope, element) {
            element.on('click', function(event){
                scope.$emit('myEvent', {secret: 'aaa'}); 
            });
        }
      }
})

function MyCtrl($scope) {
    $scope.secret = 'bbb';
    $scope.$on('myEvent', function(event, data){
        alert('event received!');
        $scope.secret = data.secret;
    });
}

      

After pressing the button, the event is received in the controller (a warning appears). However, the binding {{secret}}

does not update its value. Why?

My event creation is more complicated in real code, of course.

+3
angularjs angularjs-scope angularjs-directive


source to share


3 answers


As @Cherinv pointed out in a comment, when you change the outsite scope attributes to an Angular method, $apply

you have to call it manually. @runTarm also suggested that the event dispatcher should use $apply

because the listeners are freed from remembering it. So:

scope.$emit('myEvent', {secret: 'aaa'});

      

should be changed to:



scope.$apply(function() {
    scope.$emit('myEvent', {secret: 'aaa'});
});

      

$apply

is detailed in the following article: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

+3


source to share


USE $ scope. $ apply (). NOW the changes will be noticed and the page will be updated.



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

        myApp.directive('myEventDirective', function() {
              return {
                link: function(scope, element) {
                    element.on('click', function(event){
                        scope.$emit('myEvent', {secret: 'aaa'}); 
                    });
                }
              }
        })

        function MyCtrl($scope) {
            $scope.secret = 'bbb';
            $scope.$on('myEvent', function(event, data){
                alert('event received! secret is ' + data.secret);

                 $scope.$apply(function () {
                    $scope.secret = data.secret;        
                 });
            });
        }

      

+1


source to share


You can try changing the binding to happen to object.value rather than value. Perhaps this is the case where angular is unable to track an immutable property change.

<div ng-controller="MyCtrl">
    <button my-event-directive>Click me</button>
    <div>{{data.secret}}</div>
</div>

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

myApp.directive('myEventDirective', function() {
      return {
        link: function(scope, element) {
            element.on('click', function(event){
                scope.$emit('myEvent', {secret: 'aaa'}); 
            });
        }
      }
})

function MyCtrl($scope) {
    $scope.data = {
        secret: 'bbb'
    };
    $scope.$on('myEvent', function(event, data){
        alert('event received!');
        $scope.data.secret = data.secret;
    });
}

      

This should work.

PS since you always see the callable message, which means you don't need to call the scope. $ apply to call scope and assigned value digests, problem is angular can't look at immutable values ​​(maybe)

0


source to share







All Articles
Loading...
X
Show
Funny
Dev
Pics