Присоединение обработчика событий DOM из службы - PullRequest
0 голосов
/ 16 октября 2018

В настоящее время для присоединения обработчика событий DOM используется Renderer2.listen() на случай, если вам нужно сделать это не из шаблона.Этот подход прекрасно работает с Directive s \ Component s.

Если вам нужно сделать то же самое в Service, проблема может состоять в том, что попытка внедрить экземпляр Renderer2 вконструктор службы:

export class SomeService {
    public constructor(private readonly renderer: Renderer2) {
    }
}

приведет к отсутствию исключения провайдера DI:

StaticInjectorError (Платформа: ядро) [DefaultValueAccessor -> Renderer2]

Чтобы облегчить его, мы могли бы использовать RendererFactory2 класс для:

Создает и инициализирует пользовательский рендерер, который реализует базовый класс Renderer2.

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

Итак, вопрос в том, какова рекомендуемая практика для присоединения DOMобработчик события в сервисе?

1 Ответ

0 голосов
/ 16 октября 2018

Другие отметили, что такое поведение может быть более подходящим для Component или Directive, но интересно посмотреть, что происходит в Angular на более низком уровне.Это очень модульная структура, и это хорошая возможность узнать больше о DI изнутри.

Renderer2 немного особенный, когда дело доходит до услуг, поскольку он имеет больший контроль, когда он приходит шаблоны через внутренний Renderer2Interceptor.Он также имеет область действия , отличную от поставщиков, введенных на корневом уровне, или других глобальных поставщиков Angular: поскольку он используется для отображения шаблонов компонентов и директив, он распространяется только на эти типы объявлений.Это очень низкоуровневый провайдер, который Angular использует для создания объявлений с представлением, и по этой причине его можно внедрять в них - и поскольку сервисы также являются @Injectable, иерархия Angular DI обрабатывает их отдельно, поэтомуRenderer2 недоступен в их иерархии.

Использование RendererFactory было бы единственным способом напрямую внедрить Renderer2 в службу.

Хотя я думаю, что ваше беспокойство о том, чтобы не создавать еще один экземпляр Renderer2, является действительным, ознакомьтесь с этим комментарием к Угловому репо:

rendererFactory.createRenderer(null, null)помогло бы, если бы (конкретные) параметры не были переданы, он просто вернет средство визуализации по умолчанию без создания нового.(sic)

Итак, использование RendererFactory2.createRenderer(null, null) просто вернет значение по умолчанию DomRenderer.Фабрика существует, чтобы дать возможность создавать пользовательский рендер, и, к счастью, Angular достаточно хорошо поддерживается, чтобы не создавать дубликат DomRenderer, если фабрика вызывается.

Итак, простовведите RendererFactory2 в сервис и получите от него значение по умолчанию Renderer2.

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

...