我有一个角度控制器:
.controller('DashCtrl', function($scope, Auth) {
$scope.login = function() {
Auth.login().then(function(result) {
$scope.userInfo = result;
});
};
});
使用我创建的服务:
.service('Auth', function($window) {
var authContext = $window.Microsoft.ADAL.AuthenticationContext(...);
this.login = function() {
return authContext.acquireTokenAsync(...)
.then(function(authResult) {
return authResult.userInfo;
});
};
});
Auth服务正在使用Cordova插件,该插件位于角度世界之外。我想我不清楚何时需要使用$scope.$apply
更新您的$范围以及何时不需要。我的错误假设是因为我已将逻辑包装到角度服务中,然后在这个实例中我不需要它,但除非我将$scope.userInfo =
语句包装在$timeout
或{ {1}}。
为什么在这种情况下有必要?
答案 0 :(得分:5)
AngularJS为常见的本机JS异步行为提供包装器:
...
jQuery.ajax()=> $ HTTP
这只是带有$ scope的传统异步函数。$ apply() 最后调用,告诉AngularJS一个异步事件 发生。
所以我想因为您的Auth
服务不使用角度$http
,因此在执行异步$scope.$apply()
后,Auth
不会被角度调用功能
尽可能使用AngularJS服务而不是本机服务。如果你是 创建一个AngularJS服务(例如套接字)应该有一个 $ scope。$ apply()在触发回调的任何地方。
编辑:
在您的情况下,一旦通过换行(正如您所做)更新模型,您应该触发digest cycle:
Auth.login().then(function(result) {
$scope.$apply(function(){
$scope.userInfo = result;
});
});
或者
Auth.login().then(function(result) {
$scope.userInfo = result;
$scope.$apply();
});
答案 1 :(得分:2)
Angular不知道$scope.userInfo
已被修改,因此需要通过使用$scope.$apply
将更改应用于$scope
来执行摘要周期。
是的,$timeout
也会触发摘要周期。只有setTimeout
的Angular版本才会在运行包装代码后执行$scope.$apply
。
在您的情况下,$scope.$apply()
就足够了。
注意:$timeout
也有异常处理并返回一个承诺。