第二个ngb-tab中的模板驱动表单验证

时间:2019-11-19 14:06:25

标签: angular angular8

我在ngb-tab内部遇到了模板驱动的表单验证问题。

我想订阅位于ngb-tab中的表单的有效性更改,如下所示:

 <ngb-tab title="someTitle" id="tab-other">
    <ng-template ngbTabContent>
      <form class="animated fadeIn" #tranferInitForm="ngForm">
...
        <div class="input-group">
              <input name="benName" type="text" class="form-control" id="benName" #benName='ngModel'
                [(ngModel)]="options.benName" required [pattern]="inputPattern" maxlength="70">
              <label>some label</label>
            </div>
...
            <button class="btn btn-primary"
              [disabled]="!tranferInitForm.valid"
              (click)="onClick()">next step</button>
          </div>
        </div>
      </form>

并检查按钮[disabled]="!tranferInitForm.valid"内输入的有效性

这够了吗?

之后,我尝试添加我的组件:

@ViewChild('tranferInitForm', { static: true }) tranferInitForm;
ngOnInit() {
    this.tranferInitForm.statusChanges.subscribe(validity => {
      switch (validity) {
        case 'VALID':
          if (this._formValid) { return; }
          this._formValid = true;
          break;
        case 'INVALID':
          if (!this._formValid) { return; }
          this._formValid = false;
          break;
      }
    });
}

第一次运行会引发错误

  

错误TypeError:无法读取未定义的属性'statusChanges'

但是在那之后工作。我想是因为表单在选项卡中。

有什么想法吗?

谢谢您的时间

1 个答案:

答案 0 :(得分:1)

问题是因为在加载组件时未显示选项卡内容,这导致未定义的模板引用。 您需要将static flag设置为false才能对视图子元素进行动态查询,并等到form选项卡变为活动状态才能访问其引用。

有两种方法可以实现:

1 /最简单的方法是使用from的反应式,这样您就可以在创建表单后实现所需的逻辑。

2/2 /侦听tabChange事件,并检查nextId是否是您的表单标签ID(在您的情况下为tab-other),然后经过一段时间延迟后访问表单引用,因为在发生标签更改之前会发出tabChange事件

html

<ngb-tabset (tabChange)="onTabChange($event)">

ts

...

subscription:订阅;

...

onTabChange(event) {
    if (event.nextId === "tab-other" && !this.subscription) {
      setTimeout(() => {
        this.subscription = this.tranferInitForm.statusChanges.subscribe(
          validity => {
            switch (validity) {
              case "VALID":
                if (this._formValid) {
                  return;
                }
                this._formValid = true;
                break;
              case "INVALID":
                if (!this._formValid) {
                  return;
                }
                this._formValid = false;
                break;
            }
          }
        );
      }, 100);
    }
  }