从模板(视图)中动态加载 AngularJS 模块 [英] Dynamically loading AngularJS modules from within Templates (Views)

查看:48
本文介绍了从模板(视图)中动态加载 AngularJS 模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:为了便于论证,我们假设您有 100,000 次观看(部分观看).我们还假设您有随附的视图范围控制器,以及潜在的视图范围服务和过滤器.尝试设想一个聚合应用程序,它承载 100,000 个不同的小应用程序.

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

$routeProvider.when('/app1', {templateUrl: 'partials/view1.html',控制器:'控制器1'});

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

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

理想的解决方案: 理想情况下 - 再次对于编号为 000 的非常小的应用程序,控制器可以动态加载,并且可以从部分本身内部加载.这将减轻管理多个文件和多个配置接触点(更不用说网络请求)的需要,并很好地控制每个部分.

它看起来像这样:

在路由器中:

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

在包含 html (app-frame) 中包含相对不同的迷你应用程序":

当前托管{{appId}}


<div class="ng-include: appUrl"></div>

在使用 appUrl 的部分解析中,将控制器标记定义为一个:

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

在这种情况下,控制器和视图有很多部分和 1-1 映射,将两者结合起来以提高开发效率和维护是有意义的.这比使用多个文件和额外的配置接触点要干净得多.

问题是,这行不通.这可能就像在应用指令之前强制加载脚本一样简单......但不知道该怎么做?

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

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

使用 Angular 加载部分页面并编译控制器

来自 AngularJS 团队的 Igor 说:

我明白了.. 我们研究了在 jqlite 中支持脚本标签,但是需要做些什么才能获得跨浏览器支持涉及很多黑魔法.出于这个原因,我们决定现在我们只建议用户在这种特殊情况下使用 jquery 和 angular.我们重写三分之一的 jquery 来让它在 jqlite 中工作是没有意义的.

但我不知道他所说的使用 jquery"是什么意思......JQuery 已经从 index.html(并且在 angularjs 之前)加载到应用程序中,但听起来像我需要在局部内部做一些特别的事情.

不能通过module('app').controller(name, function() { .. }) <强>在 AngularJS 引导程序之后.为了让它工作,你应该使用 $controllerProvider.register(name, function() { .. }).

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

var app = angular.module('app', ['ui.router']);app.config(function($controllerProvider) {app.controller = 函数(名称,控制器){$controllerProvider.register(name, controller);};});

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'
    });

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.

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.

It would look something like this:

In router:

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

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

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

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>

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?

Here are some similar explanations of the problem:

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

Loading Partial Page With Angular and Compile The Controller

Igor from the AngularJS team says:

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.

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.

解决方案

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() { .. }).

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);
    };
});

这篇关于从模板(视图)中动态加载 AngularJS 模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆