为什么这不绑定?

Why does this not bind?

我正在学习 angular。我知道有很多关于 Angular 绑定的问题,但我仍在努力。也许有人可以通过这个例子让我更清楚一些。

        .controller('myCtrl',['$scope',function($scope){

            //define dummy usermanager "class" 
            var um = function(){
                this.username = 'myUsername';
            };

            //init dummy user class 
            var _um = new um();

            //Bind usermanager to scope 
            $scope.UserManager = _um;

            //After three seconds set new username 
            setTimeout(function(){
                console.log('set');
                _um.username = 'newUsername';
            },3000);
        }]);

使用基本模板

<p>{{ UserManager }}</p> 

在此示例中,它将始终显示为 { username : myUsername } 并且永远不会更改为 { username : newUsername }

如何在此示例中正确使用 Angular 的双向绑定?

编辑: 看来我可以使用 $scope.$apply();但这似乎不是最好的方法。

$scope.UserManager 指向对象 _um.

当您说 _um.username = 'newUsername' 时,这将更改 _um 对象的 属性 的值。如果在那之后你尝试 console.log($scope.UserManager.username) - 那将输出正常。

但是,当你说_um.username='newUsername'时,Angular不知道在某些范围内它是否影响了数据。因此它不会使用新的 $scope 值刷新 DOM。

您可以使用 $scope.$apply(); 调用它 (建议不要)

您可以在 AngularJS 中了解观察者 - 这可能会有所帮助。

AngularJS 实际上在 $apply 调用中调用了几乎所有代码。 ng-click、控制器初始化、$http 回调等事件都包含在 $scope.$apply() 中。所以你不需要自己调用它,事实上你不能。在 $apply 中调用 $apply 会抛出错误。

如果您要在新的回合中 运行 编码,则确实需要使用它。并且只有当那个回合不是从 AngularJS 库中的方法创建的时候。

在新的回合中,您应该将代码包装在 $scope.$apply() 中。 setTimeout 会延迟一段时间后在新的回合执行一个函数。由于 Angular 不知道该新回合,因此不会反映更新。

所以你的解决方案是使用 $scope.$apply 是完全合适的。

            $scope.$apply(function(){
                _um.username = 'newUsername';
            })

正如其他人所指出的,angular 不知道 $scope 的变化。你应该使用 $timeout 而不是将你的函数包装在 $apply

$timeout(function() {
    console.log('set');
     _um.username = 'newUsername';
}, 3000);