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

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

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

Таким образом, остается ngAfterViewInit, который, по логике вещей, должен работать, но ничего не делает, потому что документ еще не загружен. Итак, я думаю, что прослушиватель событий, как в vanilla 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!");
      }
    });

  }

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

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

Любые идеи?


person Jonathan    schedule 27.11.2020    source источник


Ответы (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 является одноэлементным, поэтому вам, возможно, придется настроить этот код и установить для обратного вызова «конец» значение 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, поэтому вам не нужно беспокоиться о нескольких вызовах.

person Andrew Alderson    schedule 27.11.2020
comment
Вот и сделал (ContentObserver) из cdk. Тем не менее, мне пришлось отказаться от подписки, так как он запускался 5 раз (вместо 20 раньше), но работал как по волшебству! - person Jonathan; 28.11.2020