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



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




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

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

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

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

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

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


EDIT



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



517   2  

2 ответов:

это просто общие советы.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

там есть директива под названием appRun

  .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 у них есть

<div app-run="todo.html" class="well"></div>

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

<script type="text/ng-template" id="todo.html">
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
    <span>{{remaining()}} of {{todos.length}} remaining</span>
    [ <a href="" ng-click="archive()">archive</a> ]
    <ul class="unstyled">
      <li ng-repeat="todo in todos">
        <input type="checkbox" ng-model="todo.done">
        <span class="done-{{todo.done}}">{{todo.text}}</span>
      </li>
    </ul>
    <form ng-submit="addTodo()">
      <input type="text" ng-model="todoText"  size="30"
             placeholder="add new todo here">
      <input class="btn-primary" type="submit" value="add">
    </form>
  </div>
</script>

у них тоже есть

<style type="text/css" id="todo.css"> //style stuff here </style>
<script id="todo.js"> //controller stuff here </script>

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

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

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

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

<div app-run="project.html" module="project" class="well"></div>

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

Comments

    Ничего не найдено.