Разработка приложения AngularJS с динамическим набором модулей

У меня есть приложение со сложным макетом, где пользователь может помещать (перетаскивать) виджеты (выбирая из предопределенного набора из 100+ виджетов), где каждый виджет представляет собой пользовательскую реализацию, которая отображает набор данных (выбирается с помощью вызова REST) определенным образом. Я'Я прочитал тонны постов в блоге, вопросы о стековом потоке и официальную документацию AngularJS, но я не могу понять, как мне разработать приложение, чтобы соответствовать его требованиям. Глядя на демонстрационные приложения, есть один модуль (ng-app), и при его создании в файле .js зависимые модули объявляются как его зависимости, однако у меня есть большой набор виджетов и как-то так ».Не стоит описывать их всех там. Мне нужно предложение по следующим вопросам:

Как мне разработать свое приложение и виджеты - должен ли я иметь отдельный модуль AngularJS или каждый виджет должен быть директивой для основного модуля?Если я создаю свой виджет как директивы, есть ли способ определить зависимость внутри директивы. То есть сказать, что моя директива использует ng-calender в своей реализации?Если я спроектирую каждый виджет как отдельный модуль, есть ли способ динамически добавить модуль виджета в качестве зависимости от основного модуля?Как я должен проектировать контроллеры - один контроллер на виджет, вероятно?Как я должен отделить состояние (область), если у меня есть несколько виджетов одного и того же типа в представлении?Есть ли лучшие практики для разработки многократно используемых виджетов с AngularJS?

РЕДАКТИРОВАТЬ

Полезные ссылки:

ocLazyLoad - отличная ленивая загрузка lib для AngularJSПроект Seed - модули + отложенная загрузка при смене маршрута (ES6, systemjs, ocLazyLoad)Ленивая загрузка в AngularJSДинамическая загрузка контроллеров и представлений с AngularJS и RequireJSЗагрузка компонентов AngularJS с RequireJS после начальной загрузки приложенияДемонстрационный проект о отложенной загрузке ресурсов AngularJS на GitHubПроект Load On DemandВнедрить модуль динамически, только если требуетсяЕще одна ленивая загрузка в Angular статьеОрганизация кода в больших приложениях AngularJS и JavaScript
 Shohel10 мая 2015 г., 05:08
Большой ресурс
 Shmiddty29 мая 2013 г., 18:11
Моей первой мыслью было бы создать каждый виджет в виде пары отдельных файлов HTML / JS, отображаемых с помощью ng-include. Хитрость заключается в том, чтобы загружать только необходимые JS-файлы контроллера.
 Shmiddty29 мая 2013 г., 23:49
Я так считаю. В вашем главном контроллере у вас будет коллекция, которая определяет, какие виджеты активны, в разметке для коллекции вы должны иметь привязку ng-include к некоторому свойству, которое указывает на указанный виджет 's view HTML src. Я'Я уверен, что это работает, но у меня нетна самом деле сделал что-то вроде этого.
 Adrian Mitev29 мая 2013 г., 18:39
Могу ли я динамически добавлять HTML, который содержит ng-include?

Ответы на вопрос(2)

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

Во-первых, они никогда не объявляютнг-приложение» приписывать. Они используют

function bootstrap() {
      if (window.prettyPrint && window.$ && $.fn.popover && angular.bootstrap &&
          hasModule('ngLocal.sk') && hasModule('ngLocal.us') && hasModule('homepage') && hasModule('ngResource')) {
            $(function(){
              angular.bootstrap(document, ['homepage', 'ngLocal.us']);
            });
      }
    }

чтобы убедиться, что все загружено правильно. Идеальная идея, но этостранно, что они так сильно надавливают на вас атрибут ng-app, чтодаже не используй это сам. В любом случае вот модуль домашней страницы, который они загружают с приложением -http://angularjs.org/js/homepage.js

Там есть директива под названием appRunI '

  .directive('appRun', function(fetchCode, $templateCache, $browser) {
    return {
      terminal: true,
      link: function(scope, element, attrs) {
        var modules = [];

        modules.push(function($provide, $locationProvider) {
          $provide.value('$templateCache', {
            get: function(key) {
              var value = $templateCache.get(key);
              if (value) {
                value = value.replace(/\#\//mg, '/');
              }
              return value;
            }
          });
          $provide.value('$anchorScroll', angular.noop);
          $provide.value('$browser', $browser);
          $locationProvider.html5Mode(true);
          $locationProvider.hashPrefix('!');
        });
        if (attrs.module) {
          modules.push(attrs.module);
        }

        element.html(fetchCode(attrs.appRun));
        element.bind('click', function(event) {
          if (event.target.attributes.getNamedItem('ng-click')) {
            event.preventDefault();
          }
        });
        angular.bootstrap(element, modules);
      }
    };
  })

Я буду использовать список дел в качестве примера. Для HTML у них есть


а затем в нижней части страницы у них есть


  Todo
  
    <span>{{remaining()}} of {{todos.length}} remaining</span>
    [ <a href="" ng-click="archive()">archive</a> ]
    
      
        
        <span class="done-{{todo.done}}">{{todo.text}}</span>
      
    
    
      
      
    
  

У них также есть

 //style stuff here 
 //controller stuff here 

Код используется, но атрибуты id в этих сценариях неЭто важно для запуска приложения. Тот'Просто для отображения исходного кода слева от приложения.

По сути, у них есть директива appRun, которая использует функцию fetchCode

  .factory('fetchCode', function(indent) {
    return function get(id, spaces) {
      return indent(angular.element(document.getElementById(id)).html(), spaces);
    }
  })

чтобы получить код. Затем они используют angular.bootstrap () для создания нового приложения. Они также могут загружать модули через приложение. Пример проекта JavaScript инициализируется как


Надеюсь, это поможет. Я'Я до сих пор не уверен, чтос "Лучший" техника, но кажется, что домашняя страница AngularJS просто использует полностью отдельное угловое приложение (ng-app) для каждого примера / виджета. Я думаю я'Я собираюсь сделать то же самое, за исключением изменения функции fetchCode, чтобы получить материал с AJAX.

 Asier Paz21 февр. 2017 г., 13:29
ты указал мне в правильном направлении. Для тех, кто заинтересован в функции hasModule, яоставлю мою реализацию здесь:function hasModule(name) { try { angular.module(name); } catch(err) { return false; } return true; }
 Dan Kanze17 июл. 2013 г., 22:16
+1 за это. У меня есть похожий вопрос, я думаю, вы могли бы помочь с:stackoverflow.com/questions/17557088/...
Решение Вопроса

Это всего лишь общие советы.

Как мне разработать свое приложение и виджеты - должен ли я иметь отдельный модуль AngularJS или каждый виджет должен быть директивой для основного модуля?

Вы'Говоря о сотнях виджетов, кажется естественным разделить их на несколько модулей. Некоторые виджеты могут иметь больше общего, чем другие виджеты. Некоторые из них могут быть очень общими и вписываться в другие проекты, другие более конкретны.

Если я создаю свой виджет как директивы, есть ли способ определить зависимость внутри директивы. То есть сказать, что моя директива использует ng-calender в своей реализации?

Зависимости от других модулей выполняются на уровне модулей, но нет проблем, если модульA зависит от модуляB и обаA а такжеB зависит от модуляC, Директивы являются естественным выбором для создания виджетов в Angular. Если директива зависит от другой директивы, вы либо определяете их в том же модуле, либо создаете зависимость на модульном уровне.

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

Я не уверен, почему вы хотите это сделать, и яЯ не уверен, как это сделать. Директивы и услуги не инициализируются до того, как они будут использованы в Angular. Если у вас есть огромная библиотека директив (виджетов) и вы знаете, чтоВозможно, я буду использовать некоторые из них, но не все, но вы нене знаю, какие из них будут использованы при инициализации приложения, вы можете на самом деле "ленивый груз ваши директивы после того, как ваш модуль был загружен. Я'мы создали примерВот

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

Как я должен проектировать контроллеры - один контроллер на виджет, вероятно?

Виджету, вероятно, понадобится собственный контроллер. Контроллеры обычно должны быть маленькими, если они становятся большими, вы можете рассмотреть, есть лиЛюбая функциональность, которая лучше всего подходит для службы.

Как я должен отделить состояние (область), если у меня есть несколько виджетов одного и того же типа в представлении?

Виджеты, которым нужны переменные области видимости, должны иметь свои собственные изолированные области видимости (scope:{ ... } в директиве конфигурации).

Есть ли лучшие практики для разработки многократно используемых виджетов с AngularJS?

Изолируйте область, сохраняйте зависимости до необходимого минимума.Смотри Мисковидео о лучших практиках в Angular

Брайан Форд также написал статью онаписание огромного приложения на Angular

 Adrian Mitev30 мая 2013 г., 07:48
Спасибо за удивительный ответ!

Ваш ответ на вопрос