AngularJS指令控制器modalInstance.result.then()中$scope值不更新问题求助
首先来说为啥会出现这个情况:AngularJS的UI Bootstrap模态框的modalInstance.result.then()回调函数,是运行在Angular的digest循环之外的。Angular只有在digest循环内部检测到作用域变化时,才会自动更新视图。所以你在这个回调里修改$scope.message的时候,Angular根本不知道数据变了,自然不会把新值渲染到视图上;而在回调外面赋值时,代码是在digest循环里执行的,所以视图能正常更新。
接下来给你几个不用$rootScope.broadcast()的解决办法:
方法1:用$scope.$apply()手动触发digest循环
在回调里修改完$scope的值后,用$apply()包裹代码,强制Angular检查作用域变化:
modalInstance.result.then(function (selectedItem) { $scope.$apply(function() { $scope.message = "模态框返回了:" + selectedItem; }); }, function () { $scope.$apply(function() { $scope.message = "模态框被取消了"; }); });
不过要注意,如果当前已经在digest循环里调用$apply()会报错,但模态框的回调肯定是在digest循环外执行的,所以这里不会有问题。
方法2:用$timeout服务自动触发digest
$timeout会把你的代码放到下一个digest循环里执行,不用手动调用$apply(),更安全:
首先记得在控制器里注入$timeout:
.directive('yourDirective', function() { return { controller: function($scope, $uibModal, $timeout) { // ... 其他代码 modalInstance.result.then(function (selectedItem) { $timeout(function() { $scope.message = "模态框返回了:" + selectedItem; }); }, function () { $timeout(function() { $scope.message = "模态框被取消了"; }); }); } }; });
$timeout的延迟参数可以留空(默认0),它会自动触发digest循环,这样视图就能同步更新了。
额外排查点:指令的作用域是否正确
因为你是在指令的控制器里操作,还要确认指令有没有使用隔离作用域(比如scope: {})。如果用了隔离作用域,控制器里的$scope和视图绑定的作用域可能不是同一个,这时候需要确保message绑定在正确的作用域上。不过你说回调外面的$scope.message能正常显示,这个可能性不大,但可以顺手排查一下。
总结一下,核心就是让Angular感知到$scope的变化,上面两种方法都能做到,完全不用依赖$rootScope的广播机制。
内容的提问来源于stack exchange,提问作者Rabin Naga

