загружен документ прослушивателя событий angular

#angular #events #angular10 #queryselector #angular-renderer2

#angular #Мероприятия #angular10 #выбор запросов #angular-средство визуализации 2

Вопрос:

Я пытаюсь выбрать все предварительные элементы в компоненте angular ПОСЛЕ загрузки документа.

ngAfterViewChecked, ngAfterContentChecked, ngAfterContentInit в основном выполняются 30 раз перед загрузкой документа, что замедлит работу моего приложения.

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

  constructor(
    @Inject(DOCUMENT) private document: Document,
    private renderer: Renderer2
 ) { }

 ngAfterViewInit(): void {

    this.renderer.listen('document', 'load', (event) => {
      console.log("loaded")
      const pres = this.document.querySelectorAll('pre');
      for (var i = 0; i < pres.length;   i) {
        console.log("Yes!");
      }
    });

  }
 

Это работает не так, как ожидалось, но я не видел, чтобы какие-либо другие методы пробовали что-то подобное, поэтому я думаю, что что-то подобное могло бы сработать.

Примечание: мои предварительные теги загружаются асинхронно из базы данных в [innerHTML]="content" .

Есть идеи?

Ответ №1:

Для этого можно использовать RendererFactory2. Это позволяет присоединить обратный вызов, который вызывается по завершении рендеринга.

 constructor(private rendererFactory: RendererFactory2) { }

  ngOnInit() {
    this.rendererFactory.end = () => {
      const pres = this.document.querySelectorAll('pre');
      for (var i = 0; i < pres.length;   i) {
        console.log("Yes!");
      }
    }
  }

 

Внимание, вводимый RendererFactory2 является одноэлементным, поэтому
вам, возможно, придется изменить этот код и установить для обратного вызова ‘end’ значение null, когда вы закончите с ним, иначе он будет продолжать вызываться.

Обновить

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

Вот документация MDN

https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

К счастью, в Angular CDK есть директива с именем cdkObserveContent, которая реализует MutationObserver. Документация здесь:

https://material.angular.io/cdk/observers/overview

Вам необходимо установить Angular CDK, если он у вас еще не установлен, и импортировать ObserversModule, а затем вы можете добавить cdkObserveContent прослушиватель к элементу DOM, в который вы вставляете html. При таком подходе прослушиватель будет запущен только один раз при вставке html, поэтому вам не нужно беспокоиться о нескольких вызовах.

Комментарии:

1. Это сделало это (ContentObserver) из cdk. Тем не менее, мне пришлось отказаться от подписки, поскольку он запускался 5 раз (вместо 20 ранее), но работал как по волшебству!