Angular不会更新绑定属性

时间:2014-08-06 07:24:47

标签: angularjs angularjs-directive angularjs-scope

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;
    });
}

单击按钮后,控制器中将收到事件(警报显示)。但是,{{secret}}绑定不会更新其值。为什么呢?

当然,我的事件创建在实际代码中更为复杂。

3 个答案:

答案 0 :(得分:3)

正如@Cherinv在评论中回复的那样,当在范围内更改范围属性Angular $apply方法时,您必须手动调用它。 @runTarm还建议事件调度程序应该使用$apply因为侦听器不会再记住它。所以:

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

应更改为:

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

$apply方法在以下文章中详细介绍:http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

答案 1 :(得分:1)

USE $ scope。$ apply()。现在注意到更改,页面也会更新。

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;        
                 });
            });
        }

答案 2 :(得分:0)

您可以尝试更改对object.value而不是value的绑定。也许就是当角度无法追踪不可变的属性变化时。

<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;
    });
}

这应该有用。

P.S。因为你总是看到被调用的警告,这意味着你不需要调用范围。$ apply调用范围摘要和值IS分配,问题是angular不能监视不可变值(可能)