动态地从内模板加载AngularJS模块(查看)

动态地从内模板加载AngularJS模块(查看)

问题描述:

背景:让我们假设为参数的缘故,你有10万人次​​(谐音)。同样假设你有随行视图范围的控制器,并有可能视图服务范围和过滤器为好。试着想象承载10万不同的小应用的聚集应用程序。

Background: Let's suppose for the sake of argument that you have 100,000 views (partials). Let's also suppose you have accompanying view-scoped controllers, and potentially view-scoped services and filters as well. Try to envision an aggregating application that hosts 100,000 disparate small applications.

问题::当您有需要附带的控制器谐音,典型的解决办法是做这样的事情:

Issue: When you have "partials" that require accompanying controllers, the typical solution is to do something like this:

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

控制器正在通过的index.html通常加载:

The controller is typically loaded from index.html via:

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

使用这种方法的问题是,它不能扩展。有解决方案在那里进行动态加载控制器,但他们仍然需要在不同配置中加入触摸点。

The problem with this approach is that it doesn't scale. There are solutions out there for dynamically loading controllers, but they still require adding touch points in various config.

理想的解决方案:理想 - 再次非常小的应用程序的数量是000的,控制器可以动态加载,并从内部部分本身。这将减轻需要管理多个文件和一些配置的接触点(更不用提网络请求),并保持每个部分很好的遏制。

Ideal Solution: Ideally - again for very small applications whose numbers are in the 000's, the controller could be loaded dynamically, and from within the partial itself. This would alleviate the need to manage several files and several configuration touch points (not to mention network requests), and keep each partial very well contained.

这将是这个样子:

在路由器:

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

在包含HTML(应用程序框架)包括相对分散的小程序:

In containing html (app-frame) include the relatively disparate "mini app":

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

在局部与appUrl解决,在一个定义控制器标记:

In partial resolved with appUrl, define controller and markup in one:

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


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

有关这样的情况下,那里有大量的泛音和一个1-1映射控制器和视图,它可以使意义夫妇两人的开发效率和维护。这比用几个文件和额外的配置接触点清洁了许多。

For cases like this, where there are a lot of partials and a 1-1 mapping for controller and view, it can make sense to couple the two for development efficiencies and maintenance. It's a lot cleaner than using several files and additional configuration touch points.

的问题是,这是行不通的。这可能是为迫使脚本之前,应用指令加载简单......但不知道该怎么做?

The problem is, this doesn't work. It could be as simple as forcing the script to load prior to applying the directive... but not sure how to do that?

下面是这个问题的一些类似的解释:

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

Loading部分页面具有角和编译器

伊戈尔从AngularJS小组说:

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),但它听起来像是我什么需要部分本身专门做一些事情。

But I don't know what he means by "use jquery" ... JQuery is already loaded into the application from index.html (and prior to angularjs), but it sounds like I need to do something specifically within the partial itself.

您无法通过模块(应用),添加新的控制器。控制器(名称,函数(){...}) 后AngularJS引导。为了使它工作,你应该使用 $ controllerProvider.register(名称,函数(){..})

You cannot add new controllers through module('app').controller(name, function() { .. }) after AngularJS bootstrap. In order make it work you should use $controllerProvider.register(name, function() { .. }).

您可以覆盖原来的控制器在下面的方式注册功能,可以添加控制器pre和POS引导:

You can override the original controller registering function in following way to be able to add controllers pre and pos bootstrap:

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

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