【问题标题】:Angular 5.2 - bypass form validation for [routerLink] while keeping focusAngular 5.2 - 在保持焦点的同时绕过 [routerLink] 的表单验证
【发布时间】:2018-09-26 15:30:36
【问题描述】:

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

我遇到一个间歇性问题,单击按钮有时会显示验证错误消息,而不是执行 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 },

【问题讨论】:

  • 您可以尝试向按钮添加(单击)事件并从那里触发 routerLink 吗?在触发路由器之前,输出一个 console.log(clickEvent);也许你可以使用 event.stopPropagation() 来避免表单验证。
  • @JoeriShoeby 感谢您推动我这样做。这是解决方案的一部分。我还需要为每个按钮定义一个模板引用变量以及 .ts 文件中关联的 ViewChild 定义。然后,我在 ngAfterViewChecked 中检查了该变量的 value 属性。奇怪的是我从不设置 value 属性。我想知道这个额外的工作是否会造成时间延迟,从而允许 click 事件在 focus() 方法可以在 ngAfterViewChecked 中运行之前触发并导航离开。我不知道。但是,再次感谢您的推动。
  • Angular 将页面更改检测为表单提交确实很奇怪。
  • 我收回了。我的“解决方案”不是解决方案。 this.cartonPartsButton.value 未定义,因此 this.focusedElement.nativeElement.focus() 从未触发。因此,按钮起作用了,但文本框没有焦点。
  • 简化问题并添加了完整的代码示例。

标签: javascript angular angular2-routing angular5 angular2-forms


【解决方案1】:

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

未指定类型属性的按钮元素表示相同 事物作为一个按钮元素,其类型属性设置为“提交”。

或者把两个超链接放到表单外面

【讨论】:

【解决方案2】:

从验证消息 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>

【讨论】:

  • @Vega 我不知道。当我使用模板变量名作为 id 时会发生什么?
  • 演示链接显示“模块'AppModule'声明的意外值'TestComponent'。请添加@Pipe/@Directive/@Component 注释。”但是,app.module.ts 对我来说看起来不错。
  • @Vega 我一直在尝试让该演示工作,但是每当我从 Test 组件单击“CartonParts”按钮时,路线就会转移到 Test2 组件,但 html 由Test2 组件看起来像 Test 组件 html。困惑。
猜你喜欢
  • 1970-01-01
  • 2012-05-12
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 2018-11-22
  • 2018-07-01
  • 1970-01-01
相关资源
最近更新 更多