我的问题情况如下,
我有一个大页面的页面(+100个输入)。这些输入分为多个部分,这些部分被开发为不同的组件(用于重用)。因此页面的总体布局是这样的,
id
每个表单部分将花费一些时间,因为大多数输入都是材料选择框,并且需要从REST API加载并处理必要的数据。
在上面显示的布局中,angular会尝试一次渲染所有表单部分,因此增加了每个部分的处理时间,这将导致浏览器冻结。
因此,我的计划是一个接一个地加载节。 有没有推荐的方法来实现这一目标?
我试图编写一个结构指令来依次加载组件。即使该指令有效,也无法得知组件何时完成其内部处理工作(可能是AfterViewInit挂钩)。该指令看起来像这样,
<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>
。
<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;
}
}
}
访问关联的组件,则此方法将无缝运行。
是否有解决此问题的建议,或者是否有其他方法可以在不更改表单节组件的情况下实现此目的?
注意:表单部分可以是任何角度分量。
答案 0 :(得分:0)
你走得太远了。
使用绑定到AfterViewInit
钩子的事件发射器:
<div>
<form-section-a (viewLoaded)="displaySectionB = true"></form-section-a>
<form-section-b *ngIf="displaySectionB" (viewLoaded)="displaySectionC = true"></form-section-b>
</div>
@Output() viewLoaded = new EventEmitter();
ngAfterViewInit() { this.viewLoaded.next(true); }
由于组件之间相互依赖,因此必须明确声明条件。
有更高级的方法(例如,使用数组),但是我敢肯定,您会找到自己的方法!
答案 1 :(得分:0)
我认为最好的解决方案是采用以下架构:
步骤管理器(此组件将处理进入和退出每个表单部分的操作)
服务
子组件
请告诉我这是否合理。
答案 2 :(得分:0)
我认为主题是满足您要求的好主意。实际上,我的应用程序中有3种形式,并且在那里使用了离子模态控制器。下面是一个简单的示例:
class OneService {
public formSubject: Subject<Object> = new Subject<Object>();
}
class ParentPage {
constructor(oneService: OneService ) {
this.oneService.formSubject.subscribe(nextStepComponentName => {
this.nextStep(nextStepComponentName);
});
}
nextStep(nextStepComponentName) {
switch nextStepComponentName:
case 'ChildComponentB':
//load it
break;
default:
this.cancel();
}
}
class ChildComponentA {
constructor(oneService: OneService ) {
}
save() {
//do save.subscribe and
this.oneService.formSubject.next('ChildComponentB');
}
}
在孩子调用subject.next()之后,然后父母知道孩子完成了。希望对您有所帮助。