Не работают директивы ангуляр

Содержание
  1. Angular. Почему не работают вложенные инклуды
  2. Обход подводных камней Angular и экономия времени
  3. №1. Пользовательская директива, которую вы применили, не работает
  4. №2. ViewChild возвращает undefined
  5. ▍Вариант решения проблемы №1
  6. ▍Вариант решения проблемы №2
  7. №3. Выполнение кода при обновлении списка, сгенерированного с помощью *ngFor (после того, как элементы появились в DOM)
  8. ▍Шаг №1
  9. ▍Шаг №2
  10. ▍Шаг №3
  11. №4. Проблемы с ActivatedRoute.queryParam, возникающие в том случае, когда запросы можно выполнять без параметров
  12. ▍Шаг №1
  13. ▍Шаг №2
  14. ▍Шаг №3
  15. №5. Медленная работа страниц
  16. Итоги
  17. Почему не работает ваше приложение Angular: 11 основных ошибок
  18. 1. Импорт обязательных модулей Angular
  19. Решение
  20. 2. Не используйте DOM ссылки пока они не созданы (@ViewChild)
  21. Проблема
  22. Решение
  23. 3. Не манипулируйте DOM напрямую — Angular Universal
  24. Решение
  25. 4. Избегайте дублирующих провайдеров, перезаписывающих друг друга
  26. 5. Angular Guards — не функция безопасности
  27. Проблема
  28. Решение
  29. 6. Объявляйте компоненты только один раз
  30. 7. Ускорьте приложение с помощью *ngIf вместо атрибута [hidden]
  31. Атрибут [hidden]
  32. Директива *ngIf
  33. 8. Избегайте проблем с обслуживанием при оборачивании в сервисы

Angular. Почему не работают вложенные инклуды

Это не статья — скорее заметка. И да, она для новичков в Angular.

Частый вопрос — почему в Angular не работают вложенные инклуды? Работают. Просто Angular — это не php.

Планируя лэйаут, мы обычно представляем что-то такое:

  • Меню сверху,
  • Меню слева,
  • Контент в центре
  • Футер

Первое что пытаемся сделать, так это добавить в главный шаблон ngView, а в шаблоны нижнего уровня добавить ngInclude. Пробуем, у нас не получается, идём читать StackOverFlow (давайте будем честны — сначала StackOverFlow, потом, может быть, если лениво не будет, — документацию).
И там нам говорят что-то в духе, “чувак, используй angular ui-router”, или “зацени, какой я себе костылесипед собрал!”.

Но давайте секундочку поразмыслим. Меню и футер — это что? Правильно — это элементы, которые используются многократно. Можно сказать, что это виджеты. Вы без сомнения в курсе, что Angular предлагает на этот счёт — директивы.

Иными словами, вложенные инклуды в Angular работают, просто надо оборачивать их в директивы. Кому-то это может показаться сложным. Но на самом деле это гораздо проще и полезнее, чем, например, вникать в angular ui-router.

Вот совственно и всё.
Для тех, кто сомневается, парочка плюсов такого подхода:.

Во-первых, улучшится читаемость — вместо абстрактного , будут более ясные теги вроде (ну или ) и так далее. Если вам это не нравится, то зачем вам angular?

Во-вторых, у директив довольно-таки много параметров, многие из которых весьма полезны. Подробнее, например здесь, или здесь.

В-третьих, опыт директив пригодиться вам в дальнейшем при работе с Angular, с другими библиотеками, вроде ui-bootstrap.

Ну и возможно главное — не надо будет завязываться на сторонние модули вроде ui-router и тратить время на их изучение, внедрение и т.п.

UPD: Минимально-необходимый код для директивы:

У нас тут точно такой же контроллер, всё как обычно и путь до темплейта. Сложно ли? Не думаю.

UPD2: Для тех, кто не понял зачем:
Я предлагаю использовать директивы в тех местах, где вы использовали ngInclude. Всё. Точка. Больше я ничего не предлагаю.
Если у вас меню на каждой странице инклудится, а такое бывает, то да — используйте вместо него директиву.
Ели вам достаточно держать меню, футер и т.п вне странице, в шаблоне верхнего уровня — значит у вас нет проблемы с вложенными инклудами.

Источник

Обход подводных камней Angular и экономия времени

С помощью Angular можно сделать всё что угодно. Или почти всё. Но иногда это коварное «почти» приводит к тому, что разработчик губит время, создавая обходные решения, или пытаясь понять, почему что-то происходит, или почему что-то не работает так, как ожидается.

Автор статьи, перевод которой мы сегодня публикуем, говорит, что хочет поделиться советами, которые помогут Angular-разработчикам сэкономить немного времени. Он собирается рассказать о подводных камнях Angular, с которыми ему (и не только ему) довелось встретиться.

№1. Пользовательская директива, которую вы применили, не работает

Итак, вы обнаружили симпатичную директиву Angular сторонней разработки и решили использовать её со стандартными элементами в шаблоне Angular. Замечательно! Попробуем это сделать:

Вы запускаете приложение… И ничего не происходит. Вы, как любой нормальный опытный программист, заглядываете в консоль инструментов разработчика Chrome. И ничего там не видите. Директива не работает и Angular хранит молчание.

Потом какая-нибудь светлая голова из вашей команды решает поместить директиву в квадратные скобки.

После этого, потеряв немного времени, мы видим в консоли следующее.

Вот в чём дело: мы просто забыли импортировать модуль с директивой

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

Поэкспериментировать с директивами можно здесь.

№2. ViewChild возвращает undefined

Предположим, вы создали ссылку на элемент для ввода текста, описанный в шаблоне Angular.

Вы собираетесь, с помощью функции RxJS fromEvent, создать поток, в который будет попадать то, что вводится в поле. Для этого вам понадобится ссылка на поле ввода, которую можно получить с помощью декоратора Angular ViewChild :

Здесь мы, с помощью функции RxJS fromEvent , создаём поток, в который будут попадать данные, вводимые в поле.
Испытаем этот код.

Собственно говоря, здесь применимо следующее правило: если ViewChild возвращает undefined — поищите в шаблоне *ngIf .

Вот он — виновник проблемы.

Кроме того, проверьте шаблон на наличие в нём других структурных директив или ng-template выше проблемного элемента.
Рассмотрим возможные варианты решения этой проблемы.

▍Вариант решения проблемы №1

Можно просто скрыть элемент шаблона в том случае, если он вам не нужен. В этом случае элемент всегда будет продолжать существовать и ViewChild сможет вернуть ссылку на него в хуке ngAfterViewInit .

▍Вариант решения проблемы №2

Ещё один способ решения этой проблемы заключается в использовании сеттеров.

Тут, как только Angular назначает свойству inputTag определённое значение, мы создаём поток из данных, введённых в поле ввода.

Читайте также:  Не работает pip install notebook

Вот пара полезных ресурсов, имеющих отношение к этой проблеме:

  • Здесь можно почитать о том, что результаты работы ViewChild в Angular 8 могут быть статическими и динамическими.
  • Если вы испытываете сложности при работе с RxJs — взгляните на этот видеокурс.

№3. Выполнение кода при обновлении списка, сгенерированного с помощью *ngFor (после того, как элементы появились в DOM)

Предположим, у вас имеется какая-нибудь интересная пользовательская директива для организации прокручиваемых списков. Вы собираетесь применить её к списку, который создан с помощью директивы Angular *ngFor .

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

Может показаться, что это можно сделать с помощью хука ngOnChanges :

Правда, тут мы встречаемся с проблемой. Хук вызывается до вывода обновлённого списка браузером. В результате пересчёт параметров директивы для организации прокрутки списка выполняется неправильно.

Как выполнить вызов сразу после того, как *ngFor завершит работу?

Сделать это можно, выполнив следующие 3 простых шага:

▍Шаг №1

Поместим ссылки на элементы туда, где применяется *ngFor ( #listItems ).

▍Шаг №2

Получим список этих элементов с помощью декоратора Angular ViewChildren . Он возвращает сущность типа QueryList .

▍Шаг №3

Класс QueryList имеет свойство changes, предназначенное только для чтения, которое выдаёт события каждый раз, когда меняется список.

Теперь проблема решена. Здесь можно поэкспериментировать с соответствующим примером.

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

Понять суть этой проблемы нам поможет следующий код.

К некоторым фрагментам этого кода сделаны комментарии вида Фрагмент #x . Рассмотрим их:

  1. В главном модуле приложения мы определили маршруты и добавили туда RouterModule . Маршруты настроены так, что если в URL не предоставлен маршрут, мы перенаправляем пользователя на страницу /home .
  2. В качестве компонента для загрузки мы указываем в главном модуле AppComponent .
  3. AppComponent использует для вывода соответствующих компонентов маршрута.
  4. Теперь — самое важное. Нам нужно получить queryParams для маршрута из URL

Предположим, что нам достался такой URL:

В таком случае queryParams будет выглядеть так:

Посмотрим на работу всего этого в браузере.

Тестирование приложения, в котором реализована система маршрутизации

Тут у вас может появиться вопрос о сути проблемы. Параметры мы получили, всё работает как ожидается…

Присмотритесь к приведённой выше копии экрана браузера, и к тому, что выводится в консоль. Тут можно заметить, что объект queryParams выдаётся дважды. Первый объект оказывается пустым, он выдаётся в ходе процесса инициализации маршрутизатора Angular. Только после этого мы получаем объект, в котором содержатся параметры запроса (в нашем случае — ).

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

Второй объект при выполнении запроса без параметров не выдаётся

В результате оказывается, что если код ожидает второго объекта, из которого он может получить данные запроса, то он не будет запущен в том случае, если в URL не было параметров запроса.

Как решить эту проблему? Здесь нам может помочь RxJs. Мы создадим на основе ActivatedRoute.queryParams два наблюдаемых объекта. Как обычно — рассмотрим пошаговое решение проблемы.

▍Шаг №1

Первый наблюдаемый объект, paramsInUrl$ , будет выдавать данные в том случае, если значение queryParams не является пустым:

▍Шаг №2

Второй наблюдаемый объект, noParamsInUrl$ , будет выдавать пустое значение только в том случае, если в URL не было обнаружено параметров запроса:

▍Шаг №3

Теперь скомбинируем наблюдаемые объекты с помощью функции RxJS merge:

Теперь наблюдаемый объект param$ выдаёт значение лишь один раз — независимо от того, содержится ли что-нибудь в queryParams (выдаётся объект с параметрами запроса) или нет (выдаётся пустой объект).

Поэкспериментировать с этим кодом можно здесь.

№5. Медленная работа страниц

Предположим, у вас имеется компонент, который выводит некие отформатированные данные:

Этот компонент решает две задачи:

  1. Он выводит массив элементов (предполагается, что эта операция выполняется однократно). Кроме того, он форматирует то, что выводится на экран, вызывая метод formatItem .
  2. Он выводит координаты мыши (это значение, очевидно, будет обновляться очень часто).

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

Много вызовов formatItem и довольно большая нагрузка на процессор

В чём же дело? А дело в том, что когда Angular перерисовывает шаблон, он вызывает и все функции из шаблона (в нашем случае — функцию formatItem ). В результате, если в функциях шаблона выполняются какие-нибудь тяжёлые вычисления, это создаёт нагрузку на процессор и влияет на то, как пользователи будут воспринимать соответствующую страницу.

Как это исправить? Достаточно выполнить вычисления, выполняемые в formatItem , заранее, и вывести на страницу уже готовые данные.

Теперь тест производительности выглядит гораздо приличнее.

Всего 6 вызовов formatItem и низкая нагрузка на процессор

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

  • Так как мы выводим координаты мыши в шаблоне — возникновение события mousemove всё ещё приводит к запуску проверки изменений. Но, так как нам нужны координаты мыши, избавиться от этого мы не можем.
  • Если же в обработчике события mousemove должны лишь выполняться некие вычисления (которые не влияют на то, что выводится на странице), тогда, чтобы ускорить приложение, можно поступить следующим образом:
  1. Можно, внутри функции-обработчика события, использовать NgZone.runOutsideOfAngular . Это позволяет предотвратить запуск проверки изменений при возникновении события mousemove (это повлияет исключительно на данный обработчик).
  2. Можно предотвратить zone.js-патч для некоторых событий, использовав следующую строку кода в polyfills.ts. Это подействует на всё Angular-приложение.

Если вас интересуют вопросы повышения производительности Angular-приложений — вот, вот, вот и вот — полезные материалы об этом.

Читайте также:  Не работает сканер canon mf4320

Итоги

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

Уважаемые читатели! Знаете ли вы о чём-то таком, что, при разработке Angular-приложений, помогает экономить время?

Источник

Почему не работает ваше приложение Angular: 11 основных ошибок

Дата публикации: 2017-11-03

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

По крайней мере, я сталкивался. После этой статьи эти ошибки больше не будут вас тормозить при разработке. Ниже мы подробно разберем все 11 ошибок. Я объясню, почему это ошибка, и укажу вам верное направление с, как минимум, одним решением.

1. Импорт обязательных модулей Angular

Возможно, самая распространенная ошибка новичков – они не импортируют обязательные модули. Почему? Потому что они о них даже не знают. Конечно, не знают. Изучение фреймворка Angular занимает какое-то время. К сожалению, часто это приводит к мистическим образом не работающим приложениям. Вы можете получить следующие ошибки: Can’t bind to ‘ngModel’ since it isn’t a known property of ‘input’

Эта ошибка значит, что вы не импортировали Angular Forms Module в модуль. Unhandled Promise rejection: No provider for HttpClient!

Эта ошибка значит, что вы не импортировали HttpClient Module в свой (корневой) модуль.

Бесплатный курс «Laravel + Angular. Быстрый старт»

Изучите курс и узнайте, как создать веб-приложение с нуля на Angular и Laravel

Решение

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

Обратите внимание: импортируйте только необходимые модули! Импорт ненужных модулей существенно раздувает вес приложения. Этот совет касается не только модулей angular. Он также касается любых модулей Angular, которые вы можете использовать, в том числе и сторонние модули. Распространенные модули, которые, возможно, необходимо импортировать:

Для сторонних библиотек хорошей практикой считается максимальное разбиение на модули. Это уменьшит вес приложения. В Angular Material, например, необходимо импортировать только модули для используемых вами компонентов. Например:

2. Не используйте DOM ссылки пока они не созданы (@ViewChild)

Декоратор @ViewChild сильно упрощает создание ссылок на дочерние элементы (HTML узлы или компоненты) компонента. Вам нужно лишь добавить ID ссылки в узел или компонент в вашем шаблоне. Просто вставьте # и далее имя, но без атрибутов узлов.

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

Angular автоматически присваивает ссылку свойству компонента, если это свойство декорировано с помощью @ViewChild(). Не забудьте передать имя ссылки в декоратор. Например, @ViewChild(‘myDiv’).

Проблема

@ViewChild() – очень полезная директива. Но нужно помнить: Ссылку на элемент можно использовать только в том случае, если элемент существует! А почему его не должно быть? Есть множество причин, по которым элемент, на который вы ссылаетесь, может не существовать.

Самая частая причина – браузер не закончил его создание и не успел добавить его в DOM. Если вы пытаетесь использовать его до создания, приложение упадет. Если вы знакомы с JS, вы, возможно, уже сталкивались с такой проблемой, так как она не специфична для Angular.

Один из примеров ссылки на DOM, который еще не создан – через конструктор компонента. Еще один пример – в жизненном цикле ngOnInit.

Это работать не будет:

Решение

Как событие DOMContentLoaded или $(document).ready() колбек в jQuery, Angular имеет такой же механизм уведомления о том, что все элементы HTML созданы. Он называется хук жизненного цикла ngAfterViewInit . Этот колбек вам и нужно использовать. Он срабатывает, когда все представления компонентов и дочерние представления инициализированы. Так безопасно (почти) получать доступ к ссылке viewChild внутри колбека.

Ура, все работает. Но стойте. Есть еще одна ловушка. Как я сказал ранее, получить доступ можно только к уже созданным элементам. Далее мы узнаем, что элементы с директивой *ngIf, которая возвращает false, полностью удаляются из DOM. То есть мы не можем получить к ним доступ в таком случае.

Чтобы предотвратить падение приложения, необходимо проверить ссылки на null. И кстати, совет относится не только к компонентам или Angular, но и к любому языку программирования.

3. Не манипулируйте DOM напрямую — Angular Universal

Прямое манипулирование DOM в Angular не только не поощряется, но и может привести к отказу приложения работать в разном ПО, отличном от браузера. Самый популярный пример — Angular Universal проект, который позволяет делать рендер приложения на сервере. Но зачем это вообще делать? Прочитайте «все о Angular universal и серверном рендере в этом пошаговом руководстве». Этот пример работать не будет

Решение

Вместо прямого изменения элементов необходимо манипулировать ими косвенно. Angular предлагает API в форме класса Renderer2. Да, 2 означает «международный», и да, был Renderer (1). Не лучшее название, но что есть.

С помощью renderer можно делать все, что и раньше при работе с DOM. Однако при работе с renderer мы точно знаем, что наш код работает на сервере так же, как и в клиенте. Вот как решается эта проблема:

1. Получите объект Renderer2, запросив его через Dependency Injection в конструкторе

2. Манипулируйте DOM косвенно с помощью renderer. Проверьте, чтобы ссылки на элементы существовали.

В Renderer2 много разных методов изменения элементов. Многие из них похожи на JavaScript DOM API. Угадать, что они делают, не должно вызвать проблем. Полный список методов можно найти в официальной документации.

Читайте также:  Не работает звук заднего хода ваз 2114

4. Избегайте дублирующих провайдеров, перезаписывающих друг друга

Вы могли слышать, что Angular использует концепцию dependency injection. С помощью dependency injection можно запрашивать объекты сервисов в конструкторе.

Чтобы это заработало, сервисы или более широкие инъекции необходимо регистрировать в секции провайдера компонента или декоратора модуля. Самый распространенный метод – предоставить его на уровне модуля.

Проблема в том, что Angular использует иерархическую систему инъекции зависимостей. То есть сервисы/инъекции в корневом модуле (AppModule) доступны всем компонентам в этом модуле. Так как этот модуль должен содержать все другие компоненты и модули, сервисы доступны во всем приложении.

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

Решение простое. Создавайте сервисы один раз в AppModule. Если вы не знаете, что делать, придерживайтесь такого подхода. Особенно в начале. В 99% случаев он будет работать.

5. Angular Guards — не функция безопасности

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

Так как guard не observable, его также нужно предоставить.

Осталось сказать ему, какие роуты защищать:

Проблема

Так что же за проблема с guards? Правда в том, что проблем с ними нет!

Но много людей путаются в названии. Они становятся проблемой, если люди неправильно понимают их назначение. Суть в том, что все, что вы делаете на стороне клиента, нельзя отнести к «безопасности». Вы отдаете потенциальным хакерам весь исходный код, и приложение может быть изменено как угодно. Т.е. наш guard можно обойти, закомментировав пару строк.

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

Решение

Если необходимо защитить любые важные данные, необходимо иметь настоящую защиту на сервере. Например, пописанный JavaScript Web Tokens.

6. Объявляйте компоненты только один раз

Чтобы компоненты работали в Angular, они должны быть объявлены в модуле. Так как у нас один модуль (AppModule), и мы регистрируем компоненты внутри него, это не проблема.

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

Компонент можно объявлять только в одном модуле!

Бесплатный курс «Laravel + Angular. Быстрый старт»

Изучите курс и узнайте, как создать веб-приложение с нуля на Angular и Laravel

Это почти все, что нужно. Но что делать, если нам необходимо использовать компонент в нескольких модулях?

Решение простое. Просто оберните компонент в модуль. Возможно, одного модуля на компонент слишком много, так почему не создать модуль компонентов? Потом этот модуль можно будет импортировать в другие модули и использовать там компоненты.

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

7. Ускорьте приложение с помощью *ngIf вместо атрибута [hidden]

Очередная распространенная ошибка – путаница с *ngIf и [hidden]. Правильный выбор может повысить производительность. Давайте рассмотрим обе техники.

Атрибут [hidden]

Атрибут hidden переключает видимость элемента. Как мы и ожидаем, так ведь? То есть если задать [hidden] в true, свойство CSS display задается в none. После этого элемент становится невидимым, но присутствует в DOM.

Проблема с атрибутом hidden в том, что выключенное CSS свойство можно легко переписать другим свойством, причем случайно. Например, если вы задали элементам display block, оно перепишет свойство display: none. То есть элемент будет всегда видимым.

Спасибо Kara Erickson, она указала на эту проблему. Более подробно по этой теме можно узнать в ее замечательной статье!

Другая теоретическая проблема – все элементы остаются в DOM, хотя они невидимы. Если речь идет о сотнях или тысячах элементов, они могут замедлить браузер. Так почему бы не удалять их, если они не нужны?

Директива *ngIf

Основное отличие директивы *ngIf в том, что вместо скрытия элементов она полностью удаляет их из DOM. Помимо возможного прироста производительности это решение также почище. Но это лишь мое мнение. Этот способ похож на стандартный способ скрытия элементов в Angular. Поэтому я почти всегда использую *ngIf.

Недостатки директивы *ngIf – ее сложно дебажить, так как удаленный элементы уже нельзя инспектировать в DOM браузера.

8. Избегайте проблем с обслуживанием при оборачивании в сервисы

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

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

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

Этого совета стоит обязательно придерживаться при использовании HttpClient. Он всегда должен быть завернут в централизованный сервис. Так он не только остается тестопригодным, но также так в него легко можно вносить изменения. Представьте, что ваш backend после недавнего обновления требует передавать с каждым запросом новый заголовок. Без централизованного сервиса вам придется искать все затронутые строки кода по всему приложению. Не нужно говорить, что это крайне не оптимально.

Вместо этого всегда оборачивайте http-запросы в сервисы. В худшем случае это никак вам не навредит. В лучшем – это сэкономит вам (и команде) часы на простейших задачах.

Источник

Оцените статью