2013-10-02 3 views
21

Благодаря отличному article from Dan Wahlin мне удалось реализовать ленивую загрузку угловых контроллеров и сервисов. Однако, похоже, нет чистого способа ленивых модулей, независимых от нагрузки.Lazy loading Модули AngularJS с RequireJS

Чтобы лучше объяснить мой вопрос, предположим, что у меня есть приложение будет структура, как показано ниже, не RequireJS:

// Create independent module 'dataServices' module with 'Pictures' object 
angular.module("dataServices", []).factory("Pictures", function (...) {...}); 

// Create 'webapp' ng-app, with dependency to 'dataServices', defining controllers 
angular.module("webapp", ['dataServices']) 
.controller("View1Controller", function (...) {...}) 
.controller("View2Controller", function (...) {...}); 

Вот пример приложения с RequireJS в Plunker:
http://plnkr.co/aiarzVpMJchYPjFRrkwn

Ядро проблема заключается в том, что Angular не позволяет добавить зависимость от ng-app после создания экземпляра. В результате мое решение заключается в использовании angular.injector для извлечения экземпляра объекта Picture, который будет использоваться в моем View2Controller. См. Файл js/scripts/controllers/ctrl2.js.

Это создает 2 проблемы для меня:

  1. инжектированных услуги выполняется вне угловых и поэтому весь асинхронный вызова должен заканчиваться $ объема $ применяется()
  2. Messy кода, в котором какой-то объект может быть введен. используя стандартный угловой синтаксис, в то время как другие требуют явного использования инжектора.

Может кто-нибудь из вас разобраться, как ленивый независимый от нагрузки модуль с использованием RequireJS и каким-то образом подключить этот модуль к угловому, так что может использоваться нормальный синтаксис зависимости угловой зависимости?

Примечание:
Вопрос на ленивой загрузке независимого модуля. Одним простым решением этого конкретного примера является создание объекта «Картинки» с использованием кэшированных поставщиков $ во время ng-app.config, но это не то, что я ищу. Я ищу решение, которое работает с сторонним модулем, например angular-resource.

+0

я обнаружил это [решение] [1] с JQuery и решимостью $ routeProvider [1]: http://stackoverflow.com/a/28199498/4504198 –

+0

@marcoseu: OFFTOPIC: пожалуйста, попробуйте тоже просмотрите этот вопрос, связанный с angularAMD. : http://stackoverflow.com/questions/31288001/how-to-use-chart-js-with-angular-chart-using-requirejs – VBMali

ответ

10

Взгляните на мой проект в GitHub: angular-require-lazy

Этот проект призван продемонстрировать идею и мотивировать дискуссии. Но делает, что вы хотите (отметьте expenses-view.js, он лениво загружает ng-сетку).

Я очень заинтересован в комментарии, идеи и т.д.


(EDIT) Угловой модуль нг сетки ленив загружается следующим образом:

  1. expenses-view.js загружается лениво, когда /expenses маршрут активирован
  2. expenses-view.js определяет ng-сетку как зависимость, поэтому RequireJs загружает ng-сетку сначала
  3. ng-g избавились это один, который вызывает angular.module(...)

Для того, чтобы достичь этого, я заменил (на самом деле) через прокси-реальный angular.module метод с моим собственным, который поддерживает лень.См. bootstrap.js и route-config.js (функции initLazyModules() и callRunBlocks()).

Эта реализация имеет свои недостатки, которые вы должны знать: функции

  1. Config не выполняются (пока). Я не знаю, можно ли lazily предоставить config-time зависимостей.
  2. Вопросы, касающиеся порядка в определениях. Если служба A зависит от B, но A определяется после B в вашем модуле, DI wil терпит неудачу. Это связано с тем, что lazyAngular proxy выполняет определения немедленно, в отличие от реального Angular, что гарантирует, что зависимости будут разрешены до выполнения определений.
+0

Интересная реализация, но на самом деле это не отвечает на мой вопрос о ленивой загрузке «угловых». модуль ", если я не упустил что-то. Ни одна из ваших зависимостей cost-view.js не закодирована с использованием «углового моделя». Но я буду помнить об этом, что я пытаюсь сделать. – marcoseu

+0

Возможно, редактирование объясняет ситуацию немного лучше. –

+0

Я скопировал ваш код в bootstrap.js, точнее все, что связано с 'makeLazyModule' и' lazyAngular.module', и оно действительно работает. Теперь, если я только понял, почему он работает ... – marcoseu

17

Я завершил мое собственное осуществление называется angularAMD и вот сайт примера, который использует его:

http://marcoslin.github.io/angularAMD/

Он обрабатывает функцию конфигурации и из определений модуля порядка.

Надеюсь, это поможет другим, кто ищет что-то, что поможет им с интеграцией RequireJS и AngularJS.

+0

Привет, я пытаюсь реализовать angularAMD. Использует ли он, чтобы следовать вашей структуре папок? Я хочу включить службы и директивы, если они находятся в разных папках? Я могу это сделать? – VishwaKumar

+0

@ VishwaKumar нет, вам не обязательно следовать моей структуре папок. Это все относительно 'baseUrl' в вашем' main.js'. – marcoseu

+0

@marcoseu: Пожалуйста, просмотрите проблему (еще не решена): https://github.com/marcoslin/angularAMD/issues/148 – VBMali

1

Похоже, что модуль Node.js ocLazyLoad определяет способ выполнения этой ленивой загрузки, хотя я не уверен, насколько это так, по сравнению с методами в других ответах или жестким кодированием зависимостей. Любая информация об этом будет оценена по достоинству. Интересно, что другим ответам требуется RequireJS, а ocLazyLoad - нет.

Похоже, что ocLazyLoad определяет другого провайдера, который вводит зависимость после того, как содержащийся модуль уже был создан. Это, по-видимому, делает это, по существу, реплицируя некоторое низкоуровневое угловое поведение, такое как загрузка и обеспечение модуля, поэтому он выглядит настолько сложным. Похоже, что он добавляет примерно каждый сердечный модуль в виде зависимости: $compileProvider, $q, $injector, ng и многие другие.