Как избежать большого количества зависимостей в Angularjs

18

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

например

app.controller('viewapps',[
    '$scope','Appfactory','Menu','$timeout','filterFilter','Notice', '$routeParams', 
    function($scope,Appfactory,Menu,$timeout,filterFilter,Notice,$routeParams) {
        //controller code..    
}])

Я уверен, что список зависимостей будет расти в будущем. Я здесь что-то не так? Правильно ли это? Каков наилучший способ эффективно справиться с этим?

    
задан harikrish 30.04.2014 в 09:27
источник

4 ответа

12

Трудно быть конкретным без точного использования или видеть точный код в вашем контроллере, но похоже, что ваш контроллер может делать слишком много (или может закончиться слишком много, поскольку вы добавляете вещи позже). 3 вещи, которые вы можете сделать:

  • Делегировать больше логики для служб, которые вставляются.

  • Отделитесь от разных контроллеров, так что каждый из них имеет только (1) ответственность.

  • Разделяйте директивы, каждая из которых имеет свои собственные контроллеры и шаблоны, а также позволяет передавать параметры и выдавать выданные атрибуты и параметр scope директивы. Это часто мой предпочтительный вариант, так как вы в итоге создаете набор повторно используемых компонентов, каждый из которых имеет мини-API.

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

ответ дан Michal Charemza 30.04.2014 в 09:53
  • У меня была фабрика для каждой таблицы DB. В одном контроллере мне нужно было запросить 6 таблиц, и мне пришлось вводить 6 фабрик + $ location + $ scope. что было слишком много. Теперь я разделил это на разные контроллеры, получая конкретные данные. Я думаю, это лучший способ ... я думаю, что ваша точка номер 2 - это то, что нужно сделать. –  harikrish 01.05.2014 в 19:28
  • Я не думаю, что это решение того, что требуется, но альтернатива. –  TNC 26.08.2015 в 10:30
7

Я играл с идеей объединения сервисов на основе контроллеров.

Итак, в вашем примере вы бы реорганизовали ваш; AppFactory, меню, filterFilter и уведомление в одном сервисе, например. ViewAppsServices.

Затем вы будете использовать свои услуги, такие как ViewAppsServices.AppFactory.yourFunction ().

Как я вижу, вы можете по крайней мере перенести свои инъекции в другой файл, немного очистив контроллер.

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

Вот JSFiddle , который я собрал, чтобы продемонстрировать, как это будет работать; это то, как я мог бы предположить, что ваша работа будет работать.

.service('ViewAppsServices', ['AppFactory', 'Menu', 'filterFilter', 'Notice', 
function (AppFactory, Menu, filterFilter, Notice) {
    return {
        AppFactory: AppFactory,
        Menu: Menu,
        filterFilter: filterFilter,
        Notice: Notice
    };
} ])
    
ответ дан aozd4v 02.09.2014 в 16:33
  • Я полагаю, это сделает мой контроллер тяжелым .. так как когда-то мне не нужны все вещи. –  Gourav Garg 13.04.2017 в 08:55
0

Постарайтесь как можно больше использовать логику для сервисов, даже просто создайте методы контроллера как методы маршрутизации - прохождения через. Со временем вы увидите, что это очень полезно, если вы захотите использовать аналогичные методы в других контроллерах / директивах. Во всяком случае, 7 инъекций, на мой взгляд, не много:)

(отредактируйте: см. комментарий Matt Way ниже) Кроме того, подсказка - в новых версиях Angular вам не нужно писать этот массив, просто:

app.controller('viewapps', function($scope,Appfactory,Menu, $timeout,filterFilter,Notice,$routeParams){
   //controller code..    
}])
    
ответ дан Jacek Kolasa 30.04.2014 в 09:36
  • Вам никогда не приходилось, но массив используется так, что вы можете делать такие вещи, как безопасно минимизировать свой угловой код. Лучше всего всегда использовать маркировку массива. –  Matt Way 30.04.2014 в 09:38
  • IMO нотация массива лучше всего оставить на этапе сборки, который может вставить его. Для меня лучшая практика - не повторять себя и оставлять эту нагрузку для машин. См. Github.com/btford/ngmin –  Jamie Pate 27.02.2017 в 22:33
-3

Мой подход заключается в использовании $injector , когда есть много зависимостей:

app.controller('viewapps', ['$scope','$injector',function($scope,$injector){                               
    var Appfactory = $injector.get('Appfactory');
    var Menu = $injector.get('Menu'); 
    //etc...
}]);

Преимущества:

  • Код может быть минимизирован и обезврежен безопасно
  • Вам не нужно подсчитывать индекс зависимости, когда вы объявляете зависимость как параметр функции
ответ дан Engineer 30.04.2014 в 09:54
  • Существуют инструменты, такие как github.com/btford/ngmin, которые предопределяют угловое значение, поэтому вы все равно можете написать функции «хороший» способ, и код в конечном итоге будет уменьшен. Кроме того, возможно ли это, по существу, маскирование списков длинных параметров, которых обычно рекомендуется избегать? stackoverflow.com/a/175035/1319998 –  Michal Charemza 30.04.2014 в 10:04
  • -1 для подхода :) Это бьет одно из основных преимуществ DI. Каждый ресурс должен быть явно о своих зависимостях. Использование $ injector обфускации фактических зависимостей ресурса (в данном случае контроллера) и убивает ремонтопригодность. (Остерегайтесь pschycopath, который в конечном итоге сохранит ваш код и knos, где вы живете. Он не будет счастлив вообще ...) –  gkalpak 30.04.2014 в 10:52
  • Данное решение с инжектором $ представляет собой реализацию шаблона Service Locator. Это анти-шаблон (в Javascript также), и его следует избегать. Кроме того, теперь вы скрываете истинную причину, которая является нарушением принципа единой ответственности. –  Steven 30.04.2014 в 14:03
  • @Steven Ваша ссылка на анти-шаблон не применима для Javascript. В любом случае браузер интерпретирует Javascript с помощью среды выполнения * (нет * вещей компиляции), и это не означает, что вы вводите службы как параметр функции или с помощью $ injector. Это почти то же самое. Я предполагаю, что вы не знакомы с Javascript и особенно с AngularJS. Я также знаю о Едином ответственном принципе, но я не знаю, почему вы упомянули об этом здесь. Ваш комментарий очень общий и вне контекста вопроса. –  Engineer 30.04.2014 в 15:19
  • @Engineer Я могу понять, почему точка в SRP будет в контексте: длинный список аргументов, который предлагает OP, будет еще длиннее, предполагает, что контроллер будет взаимодействовать со всеми введенными зависимостями. Это, в свою очередь, говорит о том, что у контроллера много обязанностей. –  Michal Charemza 01.05.2014 в 16:23
Показать остальные комментарии