Подтвердить что ты не робот

Lazy загрузки модулей AngularJS с RequireJS

Благодаря большой статье от Dan Wahlin мне удалось реализовать ленивую загрузку контроллеров и служб Angular. Тем не менее, похоже, нет чистого пути к ленивым независимым от нагрузки модулям.

Чтобы лучше объяснить мой вопрос, предположим, что у меня приложение будет структурой, как показано ниже, без 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 проблемы:

  • Введенные службы выполняются за пределами Angular, и поэтому весь асинхронный вызов должен заканчиваться на $scope. $apply()
  • Мессиальный код, в котором некоторый объект может быть введен с использованием стандартного синтаксиса Angular, в то время как другие требуют явного использования инжектора.

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

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

4b9b3361

Ответ 1

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

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

Меня очень интересуют комментарии, идеи и т.д.


(EDIT) Модуль ng-grid Angular загружается следующим образом:

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

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

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

  • Функции конфигурации не реализованы (пока). Я не знаю, можно ли лениво предоставить зависимости времени конфигурации.
  • Порядок вопросов в определениях. Если служба A зависит от B, но A определяется после B в вашем модуле, DI wil терпит неудачу. Это связано с тем, что lazyAngular proxy выполняет определения немедленно, в отличие от реального Angular, который гарантирует, что зависимости будут разрешены до выполнения определений.

Ответ 2

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

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

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

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

Ответ 3

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

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