我正在尝试在AngularJS应用程序中动态添加控制器。
在子域上,我有anotherController.js
个文件
这是anotherController.js
内容:
function anotherControllerWrapper() {
return ['$scope', '$state', function ($scope, $state) {
$scope.doWork = function () {
//...doing some work...
alert('work done');
};
$scope.doWork();
}];
};
我也写了runtimeController
提供程序,以便能够在运行时使用$controllerProvider
:
app.provider('runtimeController', function () {
var controllerProvider = null;
this.setControllerProvider = function (cp) {
controllerProvider = cp;
};
this.$get = function () {
return {
registerController: function (controllerName, controllerConstructor) {
if (!controllerProvider.has(controllerName)) {
controllerProvider.register(controllerName, controllerConstructor);
}
}
};
};
});
这是应用程序的config
部分:
app.config(function($controllerProvider, runtimeControllerProvider) {
runtimeControllerProvider.setControllerProvider($controllerProvider);
});
我通过http(在另一个控制器内部)接收控制器代码,所以它看起来像这样:
app.controller('testController', ['$scope', '$state', '$http', 'runtimeController',
function ($scope, $state, $http, runtimeController) {
$http.get('http://someUrl/anotherController.js')
.then(
function(sucess){
var evaluated = new Function('return ' + success.data)();
var ctrl = evaluated();
// routing to ui state with specified 'anotherController' works
// no 'anotherController' in app._invokeQueue
runtimeController.registerController('anotherController', ctrl);
// routing to ui state with specified 'anotherController' constanly fails
// 'anotherController' appears in app._invokeQueue
//app.controller('anotherController', ctrl);
//--registering new UI route with 'anotherController' as controller here
$state.go('anotherState');
},
function(error){ alert('something went wrong!'); },
);
}]);
Ui州也加入了dymanically,之后我添加了控制器
有人可以解释一下,发生了什么以及$controllerProvider.register
和module.controller
之间有什么区别?
答案 0 :(得分:2)
模块方法(controller
,directive
等)导致添加在应用程序初始化时执行的配置块(_configBlocks
)。一旦应用程序通过了配置阶段,它就不会执行新添加的配置块,因此app.controller(...)
在运行阶段没有效果。
正如this example所示,runtimeController
实施可以简化为
app.config(($provide, $controllerProvider) => {
$provide.value('$controllerProvider', $controllerProvider);
});
出于多种原因,应该避免{p> eval
。考虑到脚本是从CORS允许的域加载而不需要eval
编辑的,一个合适的替代方法是将其作为脚本加载。这将需要修补AngularJS API以允许延迟组件注册,类似于ocLazyLoad的操作 - 或者只是使用ocLazyLoad,因为它已经这样做了。