Javascript AngularJS module.controller vs$controllerProvider.register

Javascript AngularJS module.controller vs$controllerProvider.register,javascript,angularjs,angular-ui-router,angularjs-scope,Javascript,Angularjs,Angular Ui Router,Angularjs Scope,我正在尝试在AngularJS应用程序中动态添加控制器。 在子域上,我有另一个controller.js文件。 下面是anotherController.js内容: function anotherControllerWrapper() { return ['$scope', '$state', function ($scope, $state) { $scope.doWork = function () { //...doing some work..

我正在尝试在AngularJS应用程序中动态添加控制器。 在子域上,我有
另一个controller.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状态也是动态添加的,在我添加控制器之后。
有人能给我解释一下,
$controllerProvider.register
module.controller
之间发生了什么以及它们之间的区别吗?

模块方法(
控制器
指令
等)导致在应用程序初始化时添加一个配置块(
\u配置块
)。一旦应用程序通过配置阶段,它将不会执行新添加的配置块,因此
app.controller(…)
在运行阶段没有任何效果

如图所示,
runtimeController
实现可以简化为

app.config(($provide, $controllerProvider) => {
  $provide.value('$controllerProvider', $controllerProvider);
});

出于多种原因,应避免使用
eval
。考虑到脚本是从CORS允许的域加载的,并且不需要
eval
ed,一个合适的替代方法是将其作为脚本加载。这将需要对AngularJS API进行修补,以允许后期组件注册,类似于ocLazyLoad的做法——或者只是使用ocLazyLoad,因为它已经做到了这一点。

感谢您的解释,这就是我所要寻找的。关于
eval
-我使用了它,因为我无法预测我将需要什么样的确切脚本-我在登录后收到要从CDN下载的文件列表。谢谢你关于ocLazyLoad的建议-请看一看!不客气。不需要eval,除非您必须在脚本体中进行替换(例如,
.controller
.config
——这可以通过修补API来处理),否则您可以使用$.getScript或System.import加载脚本,或者基本上通过动态追加来加载脚本。是的,ocLazyLoad已经存在很长一段时间了,并且经过了战斗验证,所以没有必要重新发明它。