从模板(视图)中动态加载AngularJS模块

时间:2013-11-05 00:08:41

标签: angularjs angular-routing angular-template

背景:我们假设为了论证您有100,000个视图(部分)。我们还假设您具有视图范围的控制器,以及可能的视图范围的服务和过滤器。尝试设想一个托管100,000个不同的小应用程序的聚合应用程序。

问题如果您有需要附带控制器的“部分”,典型的解决方案是执行以下操作:

$routeProvider.when('/app1', {
        templateUrl: 'partials/view1.html',
        controller: 'controller1'
    });

控制器通常通过以下方式从index.html加载:

<script src="js/directives/Controller1.js"></script>

这种方法的问题在于它不能扩展。有动态加载控制器的解决方案,但它们仍然需要在各种配置中添加触摸点。

理想解决方案:理想情况下 - 对于数量在000以上的非常小的应用程序,控制器可以动态加载,也可以从部分内部加载。这样可以减少管理多个文件和几个配置触摸点(更不用说网络请求)的需要,并且可以很好地保留每个部分文件。

看起来像这样:

在路由器中:

$routeProvider.when('/apps/:appId', {
        templateUrl: 'partials/app-frame.html',
        controller: 'AppCtrl'
    });

在包含html(app-frame)中包含相对不同的“迷你app”:

<h1>Currently hosting {{appId}}</h1><hr>
<div class="ng-include: appUrl"></div>

在使用appUrl进行部分解析时,在一个中定义控制器标记:

<script>
  myApp.controller('controller1', ['$scope', function ($scope) {
    $scope.foo = "bar";
  }]);
</script>


<div ng-controller="controller1">
     {{foo}}
</div>

对于这样的情况,有很多部分和控制器和视图的1-1映射,将两者结合起来以提高开发效率和维护是有意义的。它比使用多个文件和其他配置接触点要清晰得多。

问题是,这不起作用。它可能就像在应用指令之前强制加载脚本一样简单......但不确定如何做到这一点?

以下是对该问题的一些类似解释:

https://groups.google.com/forum/#!topic/angular/H4haaMePJU0

Loading Partial Page With Angular and Compile The Controller

来自AngularJS团队的Igor说:

I see.. we looked into supporting script tags in jqlite, but what needs to be done to get a cross-browser support involves a lot of black magic. For this reason we decided that for now we are just going to recommend that users use jquery along with angular in this particular case. It doesn't make sense for us to rewrite one third of jquery to get this working in jqlite.

但我不知道他的意思是“使用jquery”... JQuery已经从index.html加载到应用程序(和angularjs之前),但听起来像我需要在部分内部专门做一些事情。

1 个答案:

答案 0 :(得分:1)

在AngularJS bootstrap 之后,您无法通过module('app').controller(name, function() { .. }) 添加新控制器。为了使其工作,您应该使用$controllerProvider.register(name, function() { .. })

您可以通过以下方式覆盖原始控制器注册功能,以便能够添加控制器pre和pos bootstrap:

var app = angular.module('app', [
    'ui.router'
]);

app.config(function($controllerProvider) {
    app.controller = function (name, controller) {
        $controllerProvider.register(name, controller);
    };
});