Angular 订阅基于条件的可观测数据
背景Angular 订阅基于条件的可观测数据,angular,observable,subscription,Angular,Observable,Subscription,背景 submit() { if(this.bookingForm.valid){ // do some actions .... } else { this.bookingForm.markAllAsTouched(); //subscribing to the event before selecting the tab this.selectedTab.animationDone.subscribe(res => {
submit()
{
if(this.bookingForm.valid){
// do some actions ....
}
else {
this.bookingForm.markAllAsTouched();
//subscribing to the event before selecting the tab
this.selectedTab.animationDone.subscribe(res => {
this.myElement.nativeElement.ownerDocument.getElementsByClassName('ng-invalid mat-form-field')[0].scrollIntoView({ behavior: 'smooth' });
});
// code to select the Tab where the error occurs .....
this.selectedTab.selectedIndex = this.errorIndex;
//unsubscribe
this.selectedTab.animationDone.unsubscribe()
} // close of else block
}// close of submit Function
Im使用的是反应式表单,它可以扩展到两个选项卡(页面的前半部分就有选项卡),然后是一个底部有Submit按钮的长页面。我在点击提交按钮时进行验证
当验证失败时,单击提交按钮,页面需要滚动到错误表单字段
我还能够根据FormGroups中的错误加载选项卡
问题
submit()
{
if(this.bookingForm.valid){
// do some actions ....
}
else {
this.bookingForm.markAllAsTouched();
//subscribing to the event before selecting the tab
this.selectedTab.animationDone.subscribe(res => {
this.myElement.nativeElement.ownerDocument.getElementsByClassName('ng-invalid mat-form-field')[0].scrollIntoView({ behavior: 'smooth' });
});
// code to select the Tab where the error occurs .....
this.selectedTab.selectedIndex = this.errorIndex;
//unsubscribe
this.selectedTab.animationDone.unsubscribe()
} // close of else block
}// close of submit Function
取消订阅(或类似功能)是必需的,因为只有在单击提交按钮时才能订阅。如果未取消订阅(或暂停),则每次更改选项卡时都会调用subscribe函数,并且页面会根据错误不断上下滚动
页面视图
这只是为了示范。
编辑下面的第2条
这是你的电话号码。这只是一个示例页面,与此相比,我的页面有更多的字段和表单组
重新创建问题
情景1
- 在这种情况下,当我多次单击Submit按钮时出现错误
- 当我第二次单击时,订阅不起作用
很抱歉反应太晚。我有点忙 我没有查看您尝试的
动画部分,而是关注基本内容,因为如果元素无效
,我们只需要关注元素
delay(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}
submit() {
if(this.testForm.valid) {
//Code to Submit
} else {
((document.getElementsByClassName('mat-input-element ng-invalid')[0]) as HTMLElement).focus();
}
}
submit() {
if(this.testForm.valid) {
//Code to Submit
} else {
((document.getElementsByClassName('mat-input-element ng-invalid')[0]) as HTMLElement).focus();
}
}
还有一件事,由于在DOM中为选项卡2
创建input
元素需要纳秒的时间,如果选项卡1
或2
中的任何一个无效,您必须在关注无效的元素之前稍微延迟一下时间
delay(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}
只需在focus()
await this.delay(1);
如果您不想设置延迟
,只需在animationDone
事件上再次设置focus()
,并将animationDuration
时间设置为最小值,这样您就不会实时看到细节1
上的focus
按照方法
链接查看完整流程,如果您遇到任何问题,请告诉我。您可以在此处粘贴更多代码吗。我不确定这是否是实现你想要做的事情的正确方法。但是你可以使用行为主体
而不是可观察的
,并在一定时间后执行下一步
。@SuyashGupta,我已经用更多细节更新了我的问题。你也可以共享你的html吗?您所说的在加载选项卡之前发生滚动是什么意思?
“批准”按钮附带了哪些所有事件?它在页面上的什么位置?我将在stackBlitz中重新创建我的问题,并在此处共享链接。谢谢您的回答。我使用延迟的方法有一个小问题。这有多愚蠢?如果加载该选项卡需要更多的时间怎么办?在我的场景中,选项卡本身是一个独立的复杂组件,它是延迟加载的。为了确保这一点,我必须订阅动画完成观察员。为了确定标签是否已加载,以下是可能的:1。动画制作;2.选择TAB改变;这两个都是可观察的。谢谢你的建议,把注意力集中在输入字段上,而不仅仅是滚动。我当然会使用它。你可以在这里验证同样的情况-因为我已经将动画持续时间设置为800 ms
,但是延迟只有1 ms
,但仍然focus()
工作正常,所以使用延迟
解决方案没有任何伤害。谢谢Suyash。我将使用延迟方法和焦点(而不是scrollIntoView)。但我仍然不相信使用延迟;但我会使用,因为我没有更好的解决方案。