背景
我使用的是“反应式表单”,该表单扩展了两个选项卡(仅页面的前半部分具有选项卡),然后是一个较长的页面,底部带有“提交”按钮。我单击“提交”按钮进行验证。
单击“提交”按钮时,验证失败时,页面需要滚动到错误表单字段。
我还能够根据FormGroups中的错误来加载选项卡。
问题
submit(){
//code to select the desired tab
this.selectedTab.animationDone.subscribe(res => {
this.myElement.nativeElement.ownerDocument.getElementsByClassName('ng-invalid mat-form-field')[0].scrollIntoView({ behavior: 'smooth' });
});
}
一切正常,直到现在!!!
单击“批准”按钮后,将订阅该订阅,并且每当选择一个新的选项卡时,页面就会滚动到错误。我想取消订阅此可观察项,以后每当再次单击“提交”按钮时就订阅。
我尝试取消订阅,但无法再次订阅。有时这会破坏订阅功能并引发错误
我认为我缺少了一些东西,正在寻求帮助。在此先感谢!!
根据要求提供更多代码
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
取消订阅(或类似功能)是必需的,因为只有在单击“提交”按钮时才应订阅。如果未取消订阅(或暂停),则每次更改选项卡时都会调用订阅功能,并且页面会根据错误不断向上和向下滚动。
浏览量
下面的编辑2
这里是StackBlitz Link。这只是一个示例页面,与此相比,“我的页面”具有更多的字段和表单组。
重新创建问题
场景1
答案 0 :(得分:1)
对不起,您的回复很晚。我有点忙。
我没有研究您尝试的animation
部分,而是专注于基础知识,因为我们只需要关注invalid
元素。
submit() {
if(this.testForm.valid) {
//Code to Submit
} else {
((document.getElementsByClassName('mat-input-element ng-invalid')[0]) as HTMLElement).focus();
}
}
I came across this very cool way to do this.
import { MatInput } from '@angular/material';
import { QueryList, ViewChildren } from '@angular/core';
@ViewChildren(MatInput) inputs: QueryList <MatInput>;
submit() {
if(this.testForm.valid) {
//Code to Submit
} else {
this.inputs.find(input => !input.ngControl.valid).focus();
}
}
此外,如果您始终希望首先选择Tab 1
,如果它是invalid
,则将其他条件放在else/ else if
部分-
if(this.testForm.get('tab1').errors) {
this.tabControl.selectedIndex = 0;
} else if(this.testForm.get('tab2').errors) {
this.tabControl.selectedIndex = 1;
}
还有一件事,您必须稍加延迟,然后再专注于invalid
元素,因为在DOM中为input
创建Tab 2
元素需要花费纳秒的时间,而专注于{如果Details 1
或Tab 1
中的任何一个为2
,则为{1}}。
invalid
只需在delay(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}
之前和focus()
之后调用它
switching tabs check
如果您不想设置await this.delay(1);
,只需在delay
事件上再次设置focus()
并将animationDone
时间设置为最短时间,这样您就不会看到{实时{1}上的{1}}。
遵循animationDuration
链接以获取完整的流程,如果您遇到任何问题,请告诉我。