Ручная загрузка AngularJS, а затем получение модуля

В общем, я бы сделал следующее, и в моем HTML будет ng-app:

var myApp = angular.module("myApp", []);

myApp.controller("AttributeCtrl", function ($scope) {
    $scope.master = {
        name: "some name"
    };
});

Однако мне нужно вручную bootstrap angular, потому что я использую его только в части моего приложения, которое загружается через jQuery $.load(). Если я сделаю следующее:

main.js - вот где страница, которую я хочу использовать angular on, вытягивается в

$("#form").load(contextPath + url, params, function() {
    angular.bootstrap($("#angularApp"));
});

И тогда страница, которую вытащили, имеет свой собственный javascript:

function AttributeCtrl($scope) {
  $scope.master = { name: "some name"};
}

Это работает, однако, в идеале, я бы хотел, чтобы мои контроллеры были охвачены на уровне модуля. Поэтому я изменил приведенный выше код таким образом

main.js

$("#form").load(contextPath + url, params, function() {
    angular.bootstrap($("#angularApp", ["myApp"]));
});

а затем...

var app = angular.module("myApp"); // retrieve a module

app.controller("AttributeCtrl", function($scope) {
  $scope.master = { name: "some name"};
});

Извлечение модуля таким образом, похоже, не работает. Я что-то делаю неправильно?

Ответ 1

Вы не можете создать контроллер после загрузки приложения. См. документацию для angular.bootstrap.

Вы должны называть angular.bootstrap() после того, как вы загрузили или определили свои модули. Вы не можете добавлять контроллеры, службы, директивы и т.д. После загрузки приложения.

Ответ 2

Я не знаю, является ли это только в приведенном здесь примере кода:

angular.bootstrap($("#angularApp", ["myApp"]));

должен быть

angular.bootstrap($("#angularApp"), ["myApp"]);

Ваш код для извлечения модуля должен работать.

Ответ 3

Обновлено

Они обновили документацию, и теперь она читается следующим образом

Каждый элемент массива должен быть именем предопределенного модуля или (DI-аннотированная), которая будет вызываться инжектором в виде прогона блок. См.: модули {@link angular.module}


Кажется, ошибка.

Способ реализации модуля правильный. Просто процитируйте его из документа, чтобы он стал понятным, так как он может быть неизвестным.

При передаче двух или более аргументов создается новый модуль. Если прошло только один аргумент, существующий модуль (имя, принятое как первое аргумент к модулю).

По проблеме, о которой вы упомянули, короткая короткая история...

Функция bootstrap вызывает createInjector с помощью списка модулей ['ng', ['ngLocale', function(){...}] , 'myApp'] (последний - это модуль, который вы передали)

function bootstrap(element, modules) {
    ...
    var injector = createInjector(modules);

Внутри createInjector() он вызывает loadModules для каждого модуля, переданного в

function createInjector(modulesToLoad) {
    forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); });

И loadModules вызывает angularModule, который инициализируется как angularModule = setupModuleLoader(window);, который создает объект window.angular.module

function loadModules(modulesToLoad){
    ....
    var moduleFn = angularModule(module); // triggers the error

Ошибка возникает, поскольку angularModule принимает второй параметр как requires. Без него в этой строке будет выбрано исключение (строка 1148) throw Error('No module: ' + name);

Сообщено: https://github.com/angular/angular.js/issues/3692

Ответ 4

Не уверен, что это считается ошибкой или решением для реализации (хотя, казалось бы, и бедным). Добавление пустого массива решает проблему undefined require, которую вы имеете, и должна решить вашу проблему в целом.

var app = angular.module("myApp", []); // create a module

app.controller("AttributeCtrl", function($scope) {
   $scope.master = { name: "some name"};
});`

Кроме того, в вашей скрипке вы вызываете {{name}}, который не будет отображаться. Вы должны называть {{master.name}}


Edit

Спасибо всем за downvotes.. Вот рабочий пример. Удачи!

http://plnkr.co/edit/UowJpWYc1UDryLLlC3Be?p=preview