我有一个现有页面,我需要将一个带有可以动态加载的控制器的角度应用程序放入其中。
这是一个片段,它根据 API 和我发现的一些相关问题实现了我对如何完成它的最佳猜测:
// Make module Foo
angular.module('Foo', []);
// Bootstrap Foo
var injector = angular.bootstrap($('body'), ['Foo']);
// Make controller Ctrl in module Foo
angular.module('Foo').controller('Ctrl', function() { });
// Load an element that uses controller Ctrl
var ctrl = $('<div ng-controller="Ctrl">').appendTo('body');
// compile the new element
injector.invoke(function($compile, $rootScope) {
// the linker here throws the exception
$compile(ctrl)($rootScope);
});
JSFiddle 。请注意,这是对实际事件链的简化,上面的行之间有各种异步调用和用户输入。
当我尝试运行上面的代码时,$compile 返回的链接器抛出: Argument 'Ctrl' is not a function, got undefined
。如果我正确理解引导程序,它返回的注入器应该知道 Foo
模块,对吧?
相反,如果我使用 angular.injector(['ng', 'Foo'])
制作一个新的注入器,它似乎可以工作,但它会创建一个新的 $rootScope
不再与 Foo
所在的元素相同的范围 ---
模块被引导。
我是在使用正确的功能来执行此操作还是我错过了什么?我知道这不是按照 Angular 的方式进行的,但是我需要将使用 Angular 的新组件添加到不使用 Angular 的旧页面,而且我不知道在引导模块时可能需要的所有组件。
更新:
我已经更新了 小提琴 以表明我需要能够在未确定的时间点向页面添加多个控制器。
原文由 Jussi Kosunen 发布,翻译遵循 CC BY-SA 4.0 许可协议
我找到了一个可能的解决方案,在引导之前我不需要了解控制器:
小提琴。唯一的问题是您需要存储
$controllerProvider
并在不应该使用它的地方使用它(在引导程序之后)。此外,似乎没有一种简单的方法可以在注册之前获取用于定义控制器的函数,因此我需要遍历模块的_invokeQueue
,这是未记录的。更新: 要注册指令和服务,而不是
$controllerProvider.register
只需分别使用$compileProvider.directive
和$provide.factory
。同样,您需要在初始模块配置中保存对这些的引用。UDPATE 2: 这是一个小提琴,它可以自动注册所有加载的控制器/指令/服务,而无需单独指定它们。