在AngularJS中,我可以在不使用DI容器的情况下访问$timeout
吗?
修改 对于那些要求“为什么”的人。我正在使用较旧版本的AngularJS,并希望创建一个实用程序函数,它将异步执行摘要。
意图是我可以在发布摘要之后将逻辑放在promise then
中以便执行,并且UI已经考虑了模型更改。
我不希望客户端代码必须使用注入器来使用所述功能。
我想要这样的东西:
我-file.js
//...
model.watchedProperty = 'new value';
// Now I want to wait for a digest to occur so that I can ensure the UI is updated before proceeding...
digestAsync(localScope)
.then(function() {
// continue...
});
// ...
消化-async.js
function digestAsync(scope) {
return $timeout(function() { // I don't want to have to use the injector...
scope.$digest();
});
}
答案 0 :(得分:2)
您可以手动获取注射器,然后获取$timeout
服务。
var $injector = angular.injector(['ng']);
var $timeout = $injector.get('$timeout');
答案 1 :(得分:1)
如果您不想注入$timeout
,可以添加$injector
作为DI,并在您的代码中添加:
$timeout = $injector.get('$timeout');
答案 2 :(得分:1)
$timeout
写成的。因此,您可以通过任何其他方式访问它来访问任何其他自编服务 - 通过依赖注入
答案 3 :(得分:0)
如果您希望在Angular摘要周期内执行回调函数,则只需使用$timeout
,如果您将0
作为间隔传递,则它将在下一个摘要中执行。
JS的setTimeout
函数将使用下一个"线程"执行回调。周期。这意味着当前线程必须先终止,然后才能执行回调。这并不意味着下一个线程周期也将是一个Angular摘要。
这在您的示例中并不重要,因为您强制使用$digest
,但您应该使用$apply
而不是$digest
。
我认为你要做的是创建一个在Angular摘要中解析的承诺。这并不适用于承诺,因为摘要不是一个需要解决的资源。
我认为您可以跳过与$timeout
相关的所有内容,并按照设计使用$apply
。
localscope.$apply(function(){
// do digest work here
});
这与以下内容相同。
$timeout(function(){
// do digest work heere
},0);
两者都可以在Angular之外执行,并且两者都将在下一个摘要周期中执行回调。如果需要,$apply
会调用$digest
,并在文档中说明了这一点。
有时您不知道$ digest是否正在进行中。
/**
* Executes the callback during a digest.
*
* @param {angular.IScope|angular.IRootScopeService} $scope
* @param {function()} func
*/
function safeApply($scope, func) {
if ($scope.$$phase) {
func();
} else {
$scope.$apply(function () {
func();
});
}
};
答案 4 :(得分:0)
由于您计划在应用程序之外使用它,因此您偶然会发现臭名昭着的'$digest already in progress'错误。为什么?因为$ digest不是异步过程,更像是它的反面。所有$digest()
函数都is calculating current scope state in loop - 没有承诺,没有超时。
这正是
不要做if(!$ scope。$$阶段)$ scope。$ apply(),它意味着你的 $ scope。$ apply()在调用堆栈中不够高。
well-known statement指的是。 “已经在进行中”的唯一时间是在$ digest期间或$apply
内触发$ digest,例如当外部JS函数用作Angular回调时。这表明应用程序设计不佳,应该进行相应的处理。
因此,$digest
函数可以向window
app.run(function ($rootScope) {
window.$digest = angular.bind($rootScope, $rootScope.$digest);
});
以同步方式使用。没有承诺。没有超时。
model.watchedProperty = 'new value';
$digest();
// 'watchedProperty' watcher has been digested ATM
我认为你已经知道为什么将Angular和外部代码混合起来被认为是一种不好的做法,应该避免使用。