Angular 5.2 - 在保持焦点的同时绕过 [routerLink] 的表单验证

Angular 5.2 - bypass form validation for [routerLink] while keeping focus

我已经完全改写了这个问题并包含了完整的代码示例。

我有一个间歇性问题,点击按钮有时会显示验证错误消息,而不是执行 router.nagivate 命令。然后,我必须单击它一秒钟才能工作。正如我所说,这是间歇性的。该解决方案需要包括以下示例的焦点行为,或者另一种方法来关注输入 html 标签。有时,我只需单击一次。为什么?而且,我怎样才能控制这种行为,使其不是随机的?

我正在发布两个测试组件来演示该问题。任何帮助将不胜感激。

test.component.html

<form novalidate #f="ngForm">
    <h2>Scan Part</h2>
    <input id="partNum" type="number" class="form-control" required [correctPart]="orderShipDetail?.UPC" name="partNum" [(ngModel)]="model.partNum" #partNum="ngModel" #partNumRef  />
    <div *ngIf="partNum.invalid && (partNum.dirty || partNum.touched)" class="text-danger">
        <p *ngIf="partNum.errors.required">PartNum is required.</p>
        <p *ngIf="partNum.errors.correctPart">Please scan the correct part. </p>
    </div>
    <button type="button" (click)="onClickCartonPartButton()">Carton Parts</button>
</form>

test.component.ts

import { Component, OnInit, AfterViewChecked, ViewChild, ElementRef } from '@angular/core';
import { Router } from '@angular/router';

class TestForm {
    constructor(
        public partNum: string = '') {
    }
}

@Component({
    selector: 'test',
    templateUrl: './test.component.html',
    styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, AfterViewChecked {

    @ViewChild('partNumRef') partNumRef: ElementRef;

    model: TestForm = new TestForm();
    public focusedElement: ElementRef;

    constructor(
        private router: Router,
        private route: ActivatedRoute
    ) { }

    ngAfterViewChecked() {
        this.focusedElement.nativeElement.focus();
    }

    ngOnInit() {
        this.focusedElement = this.partNumRef;
    }

    onClickCartonPartButton() {
        try {
            this.router.navigate(['/test2', 1006, 1248273, 1234]);
        } catch (ex) {
            console.log(ex);
        }
    }
}

test2.component.html

<a [routerLink]="['/test', 1006, 1248273, 1234, 5 ]">click this</a>

test2.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'test2',
  templateUrl: './test2.component.html',
  styleUrls: ['./test2.component.scss']
})
export class Test2Component implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

将这些路由添加到 app.module.ts

{ path: 'test/:empId/:orderNumber/:licensePlate/:orderLine', component: TestComponent },
{ path: 'test2/:empId/:orderNumber/:licensePlate', component: Test2Component },

在两个超链接上设置type="button"以避免提交

A button element with no type attribute specified represents the same thing as a button element with its type attribute set to "submit".

或者把这两个超链接放在表格外面

从验证消息 div 中的 *ngIf 中删除 partNum.touched,像这样...

<div *ngIf="partNum.invalid && partNum.dirty" class="text-danger">
    <p *ngIf="partNum.errors.required">PartNum is required.</p>
    <p *ngIf="partNum.errors.correctPart">Please scan the correct part.</p>
</div>