Как ждать отрисовки компонента или что делать, когда Angular «serve» работает, а «build» - нет? - PullRequest
0 голосов
/ 16 февраля 2019

Я создал компонент, который получает массив с табличными данными.Еще один компонент рисует таблицы.Затем я получаю innerHTML и помещаю его в tinyMCE.

Это действительно хорошо работает в ng serve, но когда я создаю ng build --prod, таблицы пусты и данные недоступны.

ngOnInit() {
    this.data = JSON.parse(JSON.stringify(this.data));

    this.tabledata = this.data.protocol;
    this.tinymceModel = "";


        setTimeout(() => {
            let root = document.querySelectorAll('[name="tabledatas"]')

            Object.values(root).forEach(elem => {
                let result = elem.innerHTML;
                    result = result.replace(/<!--.*-->/g,'')
                    result = result.replace(/\t|\n/g,'')
                    result = result.replace(/<tfoot>.*<\/tfoot>/g,'')

                this.tinymceModel = this.tinymceModel + result;
            })
        })
...
}

Код выглядит следующим образом.Я полагал, что setTimeout будет ждать, пока данные не станут доступны, но, похоже, он не работает должным образом.Где моя ошибка или как я могу убедиться в том, что после окончательного составления таблицы?

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Мы не должны использовать document.querySelectorAll в ngOnInit.Вместо этого мы должны использовать @ViewChildren в ngAfterViewInit.Примерно как следующий код.

import { ViewChildren, ElementRef, QueryList } from '@angular/core';


export class YourComponent {

    @ViewChildren('tabledatasMark') tabledatas: QueryList<ElementRef>;

    ...

    ngAfterViewInit () {
        this.tabledatas.forEach((elem: ElementRef) => {
            elem.nativeElement.innerHTML = 'HTML code you need';
        });
    }

}

Обратите внимание, что ваши элементы tabledatas должны быть помечены как '#tabledatasMark', т.е.

<div #tabledatas name="tabledatas">
... 
<div #tabledatas name="tabledatas">

PS. Заметьте, что при использовании InnerHTMLне очень хорошая идея.

0 голосов
/ 16 февраля 2019

Вместо прямого ответа на вашу проблему, я предложу вам некоторые наблюдения и соответствующие советы:

Разделение ваших данных и рендеринг по двум компонентам

Вы описываете два компонента, один из нихобработка данных, другая обработка ваших данных.Скорее всего, вы затем передаете данные через Input () / Output () между ними.

Вместо этого рассмотрите возможность использования службы для взаимодействия с данными и предлагайте эти данные вашемукомпоненты через внедрение зависимостей. Вот официальный учебник по сервисам, использующим Тур Героев , а - отличное введение в внедрение зависимостей в Angular .

Прямой доступ к свойству DOM / innerHTML дляпередать данные в ваш шаблон

Существует лишь несколько крайних случаев, когда доступ к свойству DOM / innerHTML ваших элементов следует рассматривать в качестве первого выбора.Вместо этого взгляните на угловой компонент TinyMCE . Скорее всего, его гораздо проще применить для вашего случая, чем прямой доступ к DOM.

Использование setTimeout () без аргумента в миллисекундах

При этом будет использоваться setTimeout со значением времени 0. Существует несколько вариантов использования для «разрешения перехвата рендерера» или использования его для ожидания завершения следующей микро-задачи в nodeJS. Вот подробный ответ о том, когда и как это может быть необходимо .

ng serve против ng build --prod

Я сомневаюсь, что причина вашей проблемы заключается в serve против build, более чем вероятно, что использование ng serve --prod окажет такое же влияние на вашу программу.Посмотрите это видео о различиях между разработкой и производственной сборкой.

...