Мой сценарий проблемы выглядит следующим образом,
У меня есть страница с большой формой (+100 входов). Эти входные данные разделены на разделы, и эти разделы разрабатываются как разные компоненты (для повторного использования). Итак, общий вид страницы примерно такой:
<div>
<form-section-a></form-section-a>
<form-section-b></form-section-b>
<form-section-c></form-section-c>
...
<form-section-z></form-section-z>
</div>
Обработка каждого раздела формы займет некоторое время, потому что большинство входных данных представляют собой поля выбора материала, а необходимые данные необходимо загрузить из REST API и обработать.
В приведенном выше макете angular попытается отобразить все разделы формы одновременно, тем самым суммируя время обработки каждого раздела, что приведет к зависанию браузера.
Итак, мой план состоит в том, чтобы загружать разделы один за другим. Есть ли рекомендуемый способ добиться этого?
Я попытался написать структурную директиву для загрузки компонентов один за другим. Несмотря на то, что директива работает, я никак не могу узнать, когда компонент завершил свою внутреннюю обработку (может быть, хук AfterViewInit). Директива выглядит примерно так,
<div tcSequentialRenderer>
<form-section-a *tcIfPreviousBlockLoaded></form-section-a>
<form-section-b *tcIfPreviousBlockLoaded></form-section-b>
<form-section-c *tcIfPreviousBlockLoaded></form-section-c>
...
<form-section-z *tcIfPreviousBlockLoaded></form-section-z>
</div>
.
@Directive({selector: '[tcSequentialRenderer]'})
export class SequentialRendererDirective implements AfterViewInit {
@ContentChildren(IfPreviousBlockLoadedDirective) directives: QueryList<IfPreviousBlockLoadedDirective>;
ngAfterViewInit() {
// start from first item
if (this.directives.length > 0) {
this.directives.toArray()[0].show();
}
let directivesArray = this.directives.toArray();
for (let i = 1; i < directivesArray.length; i++) {
directivesArray[i - 1].done.subscribe(status => {
if (status) {
directivesArray[i].show();
}
});
}
}
}
.
@Directive({selector: '[tcIfPreviousBlockLoaded]'})
export class IfPreviousBlockLoadedDirective {
private isShown = false;
public done: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
constructor(
private tplref: TemplateRef<any>,
private vcref: ViewContainerRef
) { }
public show(): void {
if (!this.isShown) {
this.vcref.createEmbeddedView(this.tplref);
this.isShown = true;
}
}
}
Если я каким-то образом смогу получить доступ к связанному компоненту из IfPreviousBlockLoadedDirective
, этот метод будет работать без проблем.
Есть ли какие-либо предложения по исправлению этого или есть другие способы добиться этого без изменения компонентов раздела формы?
ПРИМЕЧАНИЕ. Секции формы могут быть любым угловым компонентом.