Dynamically loading AngularJS modules from within Templates (Views)

给你一囗甜甜゛ 提交于 2019-12-01 02:25:57

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/19779687/dynamically-loading-angularjs-modules-from-within-templates-views

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!