【问题标题】:Angular $injector - Unknown Provider for Angular's $timeoutAngular $injector - Angular 的 $timeout 的未知提供者
【发布时间】:2015-10-07 19:30:25
【问题描述】:

我正在尝试将 Angular 的 $timeout 服务注入一个应该在我的应用程序的多个控制器中调用的方法中。但是,我总是收到错误消息:

错误:[$injector:unpr] 未知提供者:$timeoutProvider $timeout

当然必须知道$timeout,因为它是一个角度服务,所以我不明白为什么会发生这个错误。

这是我的代码:

HTML:
<div ng-app="app" ng-controller="sampleController">
    <button ng-click="doit()">Do It!</button>
</div>

JAVASCRIPT:
var app = angular.module('app', []);
app.controller('sampleController', ['$scope', function($scope) {
    var _this = this;

    $scope.doit = function() {
        var $injector = angular.injector();
        var $timeout = $injector.get('$timeout', _this);

        $timeout(function () { alert('ok'); });
    };
}]);

这是一个演示问题的 jsfiddle:

https://jsfiddle.net/fvw8zss5/


  • 这不是关于这是否是一种不好的做法的问题。当然是坏的。这是一个关于为什么它不起作用的问题。
  • 如果您知道如何使用 JsFiddle,JsFiddle 就可以使用。

【问题讨论】:

  • 我什至无法演奏小提琴。它说'模块“应用程序”不能被实例化'或一些。
  • 你为什么用喷油器?除非在非常特殊的情况下,否则它真的不受欢迎。
  • @sg.cc 您需要更改加载角度的方式。在左上角的框架和扩展中从 onLoad 更改为“no wrap -
  • @sg.cc Julien Roy 说的。我尝试保存为“no wrap - ”,但它总是返回“On Load”。
  • @mxa055 原因是该方法会在应用程序的多个控制器中使用。我不想为大约 25 个控制器添加相同的功能。而且我也不想为每个控制器添加 '$timeout' 依赖项。

标签: javascript angularjs


【解决方案1】:

angular.injector() 只能在每个应用程序而不是每个模块使用一次来获取注入器,您应该通过 DI 使用 $injector 来获取实例化的注入器。 话虽如此,将 ng 模块添加到列表中将通过创建新的注入器来“解决”问题(不推荐)

查看this answer 以获得完整的解释和更合适的解决方案。

【讨论】:

  • 我搜索并测试了大约 4 小时,添加 'ng' 模块解决了我的问题。非常感谢
【解决方案2】:

我想我明白你在说什么,你想要一个函数可用于所有 25 个控制器,而不必对所有 25 个控制器进行依赖注入,并且你不想提供服务,因为你必须将此服务注入所有 25 个控制器。

老实说,如果您希望此功能在 25 个控制器上可用,您将不得不对所有 25 个控制器执行 DI,无论是 $timeout、service 还是 $rootScope 方法

假设您也没有所有 25 个控制器的父控制器,这里是 $rootScope 版本:

angular.module('fooApp').run(['$rootScope', '$timeout', function($rootScope, $timeout) { 
    $rootScope.doit = function() {
       //Insert function here with $timeout        
    };
}]);

您必须将 $rootScope 注入所有控制器才能运行此功能。

我认为你最好的选择是通过恕我直言使用服务,或者至少在下次设置你的应用程序以便你有一个父控制器

【讨论】:

  • 我为每个控制器都有一个父控制器,这样我就可以向父控制器添加一个功能,并在每个控制器中都有它。这绝对不是一个好习惯(以这种方式使用 $injector),但是,就目前而言,它解决了我的问题。接下来我将把这个功能抽象成一个服务,然后把这个服务注入到所有的控制器中。
  • 啊,好吧,如果是这样,那么您可以将 $timeout 注入您的父控制器,然后从您的 25 个控制器中调用父函数,而无需执行 $injector.get。那就是如果你的父控制器是所有 25 个控制器的父级
  • 嗯,我正在使用打字稿,对于父控制器的每个子控制器,我必须复制父控制器的每个依赖项。我没有找到一种方法来设置对父项的依赖项,而在子项上,只添加那里需要的那些。 Angular 更喜欢组合而不是继承(这实际上是一种更好的选择),这就是我将应用程序架构迁移到的目标,但由于我必须使用已经完成的解决方案,我必须慢慢迁移到新架构。
【解决方案3】:

为什么不把它注入你的控制器声明中

app.controller('sampleController', ['$scope','$timeout', function($scope,$timeout)

【讨论】:

  • 因为这种方法将在大约 25 个控制器中使用(这是一个大型应用程序),我不想将此依赖项添加到所有这些控制器中。正确的方法是把这个功能变成一个服务并注入到所有的控制器中,但是现在这工作量太大了。但是,如果我找不到任何其他解决方案,那就是我要做的。
【解决方案4】:

为什么不使用指令而不是在每个控制器中重复工作?

<div ng-app="app" ng-controller="sampleController">
    <button do-it>Do It!</button>
</div>

对于脚本方面:

app.directive('doIt', function ($timeout) {
    return {
        restrict: 'A',
        link: function ($scope, $element, $attr) {
            $element.on('click', function () {
                $timeout(function () { alert('ok'); });
            });
        }
    };
});

【讨论】:

  • 如果 $timeout 中的逻辑也不依赖于控制器状态,这也可以。在这种情况下,只需将单个方法添加到控制器的超类中,这确实要容易得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 2017-04-16
  • 2017-10-08
  • 2017-08-26
  • 1970-01-01
  • 2019-07-06
相关资源
最近更新 更多