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

Angular Архитектура проекта

Я создаю приложение в angular, которое потребляет различные API-интерфейсы и предоставляет параметры для выбора пользователем, который будет записан и отправлен обратно на сервер.

Я разработал его следующим образом.

  • Вся общая логика в Main Controller и все другие опции в разных контроллерах в качестве дочернего элемента основного контроллера.
  • Главный контроллер получает все данные, необходимые для запуска приложения. который потребляется всеми другими дочерними контроллерами.
  • Чтобы убедиться, что данные загружены, я использую обещание, привязанное к области видимости. Таким образом, все дочерние контроллеры будут знать загруженные данные.
  • Я переместил часть обновления данных всех дочерних контроллеров на главный контроллер потому что все обновления происходят в одном объекте.
  • Ребенок Контроллер излучает/транслирует для связи между дочерним и основным. Поэтому, когда обновление происходит, дочерний элемент будет генерировать событие с данными, которые будут захвачены Main, и он будет выполнять обновление.
MainController {

  $scope.loaded = DataService.get();
  $scope.userOptions = {};
  $scope.$on('update',function(){
   updateUserOptions();
  })
}

ChildController {

  $scope.loaded.then(function(){
    //all logic of child controller
  }

  $scope.onselect = function(){
    $scope.$emit('update',data);
  }
}

Вопросы

  • Хорошо ли использовать события между контроллерами?
  • Хорошо ли использовать обещание, связанное с возможностями для дочерних контроллеров?
  • Будет ли улучшен мой код, если я начну использовать сервисы?
4b9b3361

Ответ 1

Я постараюсь ответить на ваш вопрос, исходя из собственного опыта. Недавно я создал одностраничное приложение, и я обновил его архитектуру.

Вот мои ответы:

  • Хорошо ли использовать события между контроллерами? IMHO, это самый гибкий способ обмена информацией между всеми контроллерами, даже если они имеют изолированную область видимости (например, с помощью $broadcast или $emit). Это называется шаблоном проектирования Observer. Однако вы можете использовать службы вместо событий для обмена данными между ними. Если вы собираетесь использовать $rootScope, будьте осторожны, поскольку все $scope наследуются от $rootScope.
  • Хорошо ли использовать обещания, связанные с возможностями для дочерних контроллеров? Во-первых, вам нужно узнать, как работает наследование областей. Вы должны позаботиться о том, чтобы избежать тени собственности в JS. Во-вторых, я бы отключил всю логику от scope.loaded в ChildController до такой службы, как ChildService. Сохранение бизнес-логики (например, запроса и т.д.) В службах вместо контроллеров гарантирует ее повторное использование. Разделение бизнес-логики - хороший принцип проектирования.
  • Будет ли улучшен мой код, если я начну использовать сервисы? Я ответил на этот вопрос выше.

Кроме того, чтобы построить хорошую архитектуру, я прочитал этот angular руководство по стилю, написанное Джоном Папой.

Я рекомендую следующие изменения:

  • Чтобы убедиться, что данные загружены, я использую обещание, привязанное к области видимости. Таким образом, все дочерние контроллеры будут знать загруженные данные. Вместо этого я бы выбрал пользовательское "загруженное" событие в MainController с помощью $scope.$emit('loaded'). После этого в ChildController я использовал бы $scope.$on('loaded', function(){}) для обработки события.
  • Я бы переместил функцию updateUserOptions в службу и ввел ее только в те контроллеры, которые в ней нуждаются.

Я надеюсь, что это поможет!

Ответ 2

Хорошо ли использовать события между контроллерами? Не как основная форма обмена данными, но вы можете использовать ее для уведомления о системных событиях, таких как готовность к данным.

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

Будет ли улучшен мой код, если я начну использовать сервисы? Да.

Это то, что я сделал бы на вашем месте:

dataService - эта служба отвечает за все входящие/исходящие данные. Всякий раз, когда выполняется запрос данных (независимо от того, какой контроллер запрашивает данные), служба кэширует данные (сохранение обещания достаточно хорошее). Все дальнейшие запросы получают кэшированные данные, если они не указывают, что им нужны свежие данные. Всякий раз, когда данные обновляются (1-й раз или обновляется), служба передает событие dataReady через $rootScope, к которому может прослушиваться основной контроллер и другие подписчики. Служба также отвечает за обновления данных, а когда данные обновляются, вы также можете транслировать событие через $rootScope. Когда событие активировано, все абоненты обращаются к службе и получают нужные им данные.

Контроллеры - избегают контроллеров, используют директивы с изолированной областью и передают данные между ними с помощью атрибутов. Таким образом, вы можете быть уверены, что каждая директива получает то, что ей нужно, и не все. Директивы могут связываться с использованием атрибутов, служб, трансляции/испускать или требовать от своих родителей/братьев и сестер, если они тесно сотрудничают.

Ответ 3

  • Хорошо ли использовать события между контроллерами?

Нет, нет, он будет устарел Angular JS 2.0. Это также часто приводит к неуправляемому клубу событий, которые трудно понять и отлаживать. Используйте службы для обмена данными между контроллерами. (Внедряйте одну и ту же услугу на несколько контроллеров, служба затем хранит данные, контроллеры привязываются к этим данным и автоматически синхронизируются). Я написал сообщение в блоге, объясняющее это использование случай.

  1. Хорошо ли использовать обещания, связанные с возможностями для дочерних контроллеров?

Нет, нет. Используйте promises и разрешайте данные в службах. Не используйте $scope вообще, но используйте вместо синтаксиса controllerAs. $scope устарела и в Angular JS 1.X, потому что ее использование приводит к множеству различных проблем с наследованием области.

  1. Будет ли улучшен мой код, если я начну использовать сервисы?

ДА! Используйте службы для всей логики и обработки данных. Используйте контроллеры только для взаимодействия с пользовательским интерфейсом и делегируйте все услуги. Также используйте ui-router для управления состоянием вашего приложения.

Ответ 4

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

  • Вся общая логика в Main Controller и все другие опции в разных контроллерах в качестве дочернего элемента основного контроллера.

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

Исправление: я предлагаю создать службу, которая извлекает данные с сервера, и вводить эту службу в контроллеры по мере необходимости. Также обратите внимание, что этот способ обеспечивает лучшее управление зависимостями, так как вы можете отслеживать, какие контроллеры нуждаются в каких именно услугах.

  1. Следует избегать вложенных контроллеров, когда это возможно, потому что angular отслеживает все активные области и повторно оценивает их в каждом цикле $apply().

Исправление: то же, что и # 1, используйте сервисы вместо основного контроллера.

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

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

  1. Я переместил часть обновления данных всех дочерних контроллеров на главный контроллер, потому что все обновления происходят в одном объекте.

Ребенок Контроллер излучает/транслирует связь между дочерним и основным. Поэтому, когда обновление происходит, дочерний элемент будет генерировать событие с данными, которые будут записаны в Main, и он сделает обновление.

Исправить: используйте службу с функцией update вместо событий. События сложнее отлаживать и отслеживать. И вам нужно отменить регистрацию обработчиков событий при уничтожении контроллера. Если вы можете использовать функцию/обещание вместо событий, тогда это обычно лучшая идея.

Ответ 5

Хорошо ли использовать события между контроллерами?

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

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

Вы все равно можете реализовать шаблон наблюдателя с помощью службы.

Хорошо ли использовать обещание, привязанное к области для дочерних контроллеров?

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

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

Будет ли улучшен мой код, если я начну использовать сервисы?

Я думаю, что приведенные выше ответы уже набросают ответ на этот вопрос: да. Есть и другие преимущества, но этот формат не подходит для слишком длинных ответов, поэтому я больше ничего не буду перечислять.

В целом, эти указатели не являются большими проблемами с вашим кодом в настоящее время, но если вы ищете лучшую архитектуру, я думаю, что вы можете сделать лучше.

Ответ 6

Ответы:

  • Нет, скоро это будет устаревшим.

  • $scope уже устарел.

  • Услуги - отличный выбор. Сервисы позволяют обмениваться данными и поведением с другими объектами, такими как контроллеры.