我可以在不使用DI容器的情况下访问$ timeout吗?

时间:2015-10-13 13:02:38

标签: javascript angularjs

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

5 个答案:

答案 0 :(得分:2)

您可以手动获取注射器,然后获取$timeout服务。

var $injector = angular.injector(['ng']);
var $timeout = $injector.get('$timeout');

答案 1 :(得分:1)

如果您不想注入$timeout,可以添加$injector作为DI,并在您的代码中添加:

$timeout = $injector.get('$timeout');

答案 2 :(得分:1)

不,你不能。很多角都是以角度including $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和外部代码混合起来被认为是一种不好的做法,应该避免使用。