Laden eines AngularJS-Controllers dynamisch

Ich habe eine vorhandene Seite, in die ich eine eckige App mit Controllern ablegen muss, die dynamisch geladen werden können.

Hier ist ein Ausschnitt, der meine besten Vermutungen darüber umsetzt, wie es basierend auf der API und einigen verwandten Fragen, die ich gefunden habe, gemacht werden sollte:

// Make module Foo
angular.module('Foo', []);
// Bootstrap Foo
var injector = angular.bootstrap($('body'), ['Foo']);
// Make controller Ctrl in module Foo
angular.module('Foo').controller('Ctrl', function() { });
// Load an element that uses controller Ctrl
var ctrl = $('<div ng-controller="Ctrl">').appendTo('body');
// compile the new element
injector.invoke(function($compile, $rootScope) {
    // the linker here throws the exception
    $compile(ctrl)($rootScope);
});

JSFiddle. Beachten Sie, dass dies eine Vereinfachung der tatsächlichen Ereigniskette darstellt. Zwischen den obigen Zeilen befinden sich verschiedene asynchrone Aufrufe und Benutzereingaben.

Wenn ich versuche, den obigen Code auszuführen, gibt der Linker, der von $ compile zurückgegeben wird, Folgendes aus:Argument 'Ctrl' is not a function, got undefined. Wenn ich Bootstrap richtig verstanden habe, sollte der zurückgegebene Injektor über das wissenFoo Modul, richtig?

Wenn ich stattdessen einen neuen Injektor benutzeangular.injector(['ng', 'Foo'])Es scheint zu funktionieren, aber es schafft eine neue$rootScope Das ist nicht mehr derselbe Bereich wie das Element, in dem dieFoo Modul wurde gebootet.

Verwende ich die richtige Funktionalität, um dies zu tun, oder gibt es etwas, das ich verpasst habe? Ich weiß, dass dies nicht auf die Angular-Art erfolgt, aber ich muss alten Seiten, die dies nicht tun, neue Komponenten hinzufügen, die Angular verwenden, und ich kenne nicht alle Komponenten, die beim Booten des Moduls erforderlich sein könnten.

AKTUALISIEREN:

Ich habe das aktualisiertGeige um zu zeigen, dass ich in der Lage sein muss, der Seite zu unbestimmten Zeitpunkten mehrere Controller hinzuzufügen.

Antworten auf die Frage(8)

Ihre Antwort auf die Frage