Angular-等到我收到数据后再加载模板 [英] Angular - Wait until I receive data before loading template
问题描述
因此,我有一个可以使用此模板动态呈现多个组件的组件:
<div [saJquiAccordion]="{active: group.value['collapsed']}" *ngFor="let group of filterGroupsTemplate | keysCheckDisplay;">
<div>
<h4>{{group.key | i18n}}</h4>
<form id="ibo-{{group.key}}" class="form-horizontal" autocomplete="off" style="overflow: initial">
<fieldset *ngFor="let field of group.value | keys">
<ng-container *ngComponentOutlet="fieldSets[field.value.template];
ngModuleFactory: smartadminFormsModule;"></ng-container>
</fieldset>
</form>
</div>
</div>
问题是填充我从API调用中获取的那些组件所需的数据:
this.getFiltersSubscription = this.getFilters().subscribe(
(filters) => {
this.filters = filters;
log.info('API CALL. getting filters');
// Sending data to fieldform components
this.iboService.updateIBOsRankList(filters['iboRank'].data);
this.iboService.updateIBOsNewsletterOptions(filters['iboNewsletter'].data);
this.iboService.updateIBOsTotalOrders(filters['iboTotalOrders'].data);
}
);
因此,一旦我有了我的数据,就会触发一个Observable服务,我的组件已订阅,然后它们将处理收集的数据.
So, once I have my data, I'm triggering a service Observable which my components are subscribed to, and they will then process the gathered data.
问题:
如果在所有组件加载之前进行API调用,我将触发这些服务方法传递数据,但是没有人将订阅这些Observable.
一种方法是:
首先加载数据,并且只有在加载数据后,我才会渲染模板,因此,将动态渲染所有这些组件,然后才触发这些服务方法(Observables).
Load data first, and only when I have the data loaded, I'll render the template and, therefore, render all these components dynamically and only then I'll be triggering these service methods (Observables).
我不想为每个组件进行API调用,因为它可能像60个组件,我宁愿放松代码的抽象性,但我愿意做这样的事情:
I don't want to make an API call for each component, because it can be like 60 components, I'll rather loose abstraction fo code but I preffer to do something like this:
// Listens to field's init and creates the fieldset triggering a service call that will be listened by the field component
this.iboService.initIBOsFilters$.subscribe(
(fieldName) => {
if (fieldName === 'IBOsRankSelectorFieldComponent') {
log.data('inside initIBOsFilters$ subscription, calling updateIBOsFilters()', fieldName);
this.iboService.updateIBOsRankList(this.filters['iboRank'].data); // HERE I'M PASSING DATA TO THE COMPONENT RENDERED DYNAMICALY. BUT IF this.filters IS UNDEFINED, IT BREAKS
}
}
);
为此,我需要确保定义了this.filters
,因此得出结论:
In order to do this, I need to ensure that this.filters
is defined and thus, I come to conclusion:
如何在呈现模板html之前等待API调用结束并定义this.filters
?
How can I wait until API call ends and this.filters
is defined before rendering my template html?
对不起,如果我的问题有点长,如果您需要更多详细信息,请告诉我.
Sorry if my question is a bit long, if you need any more details just let me know.
谢谢!
推荐答案
研究了人们给我的不同方法后,我在async
管道上找到了解决方案.但是,我花了一些时间来了解如何实现它.
After studying the different approaches that people gave me, I found the solution on the async
pipe. But, it took me a while to understand how to implement it.
解决方案:
// Declaring the Promise, yes! Promise!
filtersLoaded: Promise<boolean>;
// Later in the Component, where I gather the data, I set the resolve() of the Promise
this.getFiltersSubscription = this.getFilters().subscribe(
(filters) => {
this.filters = filters;
log.info('API CALL. getting filters');
this.filtersLoaded = Promise.resolve(true); // Setting the Promise as resolved after I have the needed data
}
);
// In this listener triggered by the dynamic components when instanced,
// I pass the data, knowing that is defined because of the template change
// Listens to field's init and creates the fieldset triggering a service call
// that will be listened by the field component
this.iboService.initIBOsFilters$.subscribe(
(fieldName) => {
if (fieldName === 'IBOsRankSelectorFieldComponent') {
log.data('inside initIBOsFilters$ subscription, calling updateIBOsFilters()', fieldName);
this.iboService.updateIBOsRankList(this.filters['iboRank'].data);
}
}
);
在模板中,我使用需要Observable
或Promise
In the template, I use the async
pipe that needs an Observable
or a Promise
<div *ngIf="filtersLoaded | async">
<div [saJquiAccordion]="{active: group.value['collapsed']}" *ngFor="let group of filterGroupsTemplate | keysCheckDisplay;">
<div>
<h4>{{group.key | i18n}}</h4>
<form id="ibo-{{group.key}}" class="form-horizontal" autocomplete="off" style="overflow: initial">
<fieldset *ngFor="let field of group.value | keys">
<ng-container *ngComponentOutlet="fieldSets[field.value.template];
ngModuleFactory: smartadminFormsModule;"></ng-container>
</fieldset>
</form>
</div>
</div>
</div>
注意:
-
根据我的理解,
-
async
管道需要一个Observable
或Promise
,这就是为什么使其唯一起作用的方法是创建一个Promise
- 我没有使用
resolver
方法,因为当您通过Angular的路线到达组件时会使用它.该组件是较大组件的一部分,并且不像其他任何常规组件一样通过路由进行实例化. (不过尝试了这种方法,做了一点努力,却没有完成工作)
async
pipe need anObservable
or aPromise
from what I understood, that's why the only way to make it work was by creating aPromise
- I didn't use the
resolver
approach because it's used when you arrive to the component through Angular's routing. This component is part of a larger component and it's not instanced through routing like any other normal component. (Tried that approach though, worked a bit with it, didn't do the job)
这篇关于Angular-等到我收到数据后再加载模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!