在angularjs中动态加载控制器+工厂

时间:2014-11-08 22:46:22

标签: javascript angularjs angular-services

我正在开发应该可以使用“addins”扩展的angularjs应用程序。在简化的情况下,addin只是一对js + html文件。每个插件应该有一个或多个控制器和一个或多个工厂。 下面是添加一个控制器和一个工厂的示例:

JS:

angular.module('addins.basic', [])

angular.module('addins.basic').factory('BasicAddinFactory', [BasicAddinFactory]);

function BasicAddinFactory()
{
    var fact =
    {
        Invoke: function ()
        {
            console.log('BasicAddinFactory.Invoke');
        },
        GetClients: function ()
        {
            return ["aa", "bb"];
        }
    }

    return fact;
}

angular.module('addins.basic').controller('BasicAddinController', ['$scope', 'BasicAddinFactory', BasicAddinController]);

function BasicAddinController($scope, $injector, addin)
{
    //var injector = angular.injector(['ng', 'addins.basic'])
    //var addin = injector.get('BasicAddinFactory');

    $scope.expr = 'BasicAddinFactory: ' + addin.GetClients()[0];
}

HTML:

<div ng-controller="BasicAddinController">
    <input type="text" ng-model="expr">
    <span>{{ expr }}</span>
</div>

使用互联网上广泛描述的技术动态加载插件不是问题:通过向DOM添加JS脚本和HTML。一切都很好,直到我尝试将BasicAddinFactory的依赖注入BasicAddinController。这样做后我在动态加载过程中出错:未知提供者:addinProvider&lt; - addin。

有趣的是,如果我没有明确地注入依赖项,那么一切都很好,我甚至可以通过使用上面示例中的注释代码从控制器(或从加载“addin”的父代码)访问工厂实例。但这很难看,我真的不想这样做。

如果有人能指出我的错误,我将不胜感激。

感谢。

更新:Sample plunk

1 个答案:

答案 0 :(得分:3)

这与Angular如何实际处理幕后的依赖关系有关。 bootstrap进程处理注册所有各种服务。

当您动态添加模块时,您需要自己注册这些新模块。一种方法是为每种类型的服务提供全局可用的寄存器功能,如下所示:

app.config(['$controllerProvider',
  '$compileProvider', '$filterProvider', '$provide',
  function($controllerProvider,
    $compileProvider, $filterProvider, $provide) {

    app.register = {
      controller: $controllerProvider.register,
      directive: $compileProvider.directive,
      filter: $filterProvider.register,
      factory: $provide.factory,
      service: $provide.service
    };
  }
]);

然后,您可以更改动态模块以注册其服务:

app.register.factory('BasicAddinFactory', [BasicAddinFactory]);

A Plunker example.