【问题标题】:Angular 6 - ng-dirty and ng-invalid not working as expectedAngular 6 - ng-dirty 和 ng-invalid 未按预期工作
【发布时间】:2018-10-31 08:28:29
【问题描述】:

我正在尝试一些表单验证,并从应用于表单控件的类中看到奇怪的行为。

当我将输入值从“Rob”更改为“Ro”时,不会应用ng-dirty,但当我将值进一步更改为“R”时,它确实会应用。

ng-invalid 在我清除表单字段并且存在必需属性时不会被应用。但是,如果我模糊不清,则会应用该课程。

代码链接 - https://stackblitz.com/edit/angular-form-classes

我做错了什么?请告诉我谢谢。

【问题讨论】:

    标签: angular angular6


    【解决方案1】:

    当模板引用变量username 在 DOM 中定义后使用时,它可以正常工作。根据我的测试,可以在form标签的内部或外部使用,只要在输入元素声明之后即可。

    请参阅this stackblitz 以获取演示。

    <form #userForm="ngForm" ngForm>
      <div class="form-group">
        <label>Name</label>
        <input type="text" #userName required class="form-control" name="name" [(ngModel)]="userModel.name">
      </div>
    </form>
    {{userName.className}}  <<-- Works when positioned after userName definition in the DOM
    

    【讨论】:

    • 所以得出结论模板引用变量应该在定义之后而不是之前使用
    • @Vikas - 这是我第一次看到这一点,但也许我从未尝试在 DOM 中声明模板引用变量之前使用它。我也没有在文档中找到有关该范围限制的任何内容。
    • 更正我之前的评论:这并不是真正的范围限制,而是在评估模板中的值时对时间的影响。
    • 感谢@ConnorsFan。我不知道在 temp ref 变量之前使用它会影响它的工作方式。如果有人提出任何类似的问题,我会检查 repo 以尝试了解更多。
    【解决方案2】:

    我不得不承认我并不完全理解这背后的原因,但是您在尝试显示的 userName.className 上遇到了“ExpressionChangedAfterItWasChecked”错误。似乎首先检查userName.className,然后根据更新它的事件检查表单状态,所以它总是落后一步。您可以通过执行额外的更改检测引用循环来同步这些值。

    ChangeDetectorRef 注入到您的组件中,并在检查完视图后运行detectChanges()

    import { Component, AfterViewChecked, ChangeDetectorRef } from '@angular/core';
    import { User } from './user';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent implements AfterViewChecked {
      name = 'Angular 6';
      topics = ['Angular', 'React', 'Vue'];
      userModel = new User('Rob', 'rob@test.com', 5556665566, 'Angular', 'morning', true);
    
      constructor(private ref: ChangeDetectorRef) {}
    
      ngAfterViewChecked() {
        this.ref.detectChanges();
      }
    }
    

    【讨论】:

    • 但是为什么会这样呢?这不是预期的行为吗?我在 Angular 2 中尝试过这种方式并且工作正常。我检查了官方文档示例并且工作正常 - stackblitz.com/angular/oyykrkdkgryv
    • 这是正确的解决方案。异步事件(输入字段更改)运行更改检测,然后模板表达式根据该更改的值进行评估(但它不会触发新的更改检测周期),因此总是落后一步。这就是为什么手动触发它使其工作。
    【解决方案3】:

    发生的情况是,您总是落后一个更改检测步骤(使用插值类名),因为您正在更改模型,这反过来会更改输入字段的值,然后您正在复制该输入字段值(通过模板变量)到其他地方。

    试试这个堆栈闪电战: https://stackblitz.com/edit/angular-form-classes-q97pah?file=src%2Fapp%2Fapp.component.ts

    您在这里收听ngModelChange,一旦它发生,在下一个滴答声 (setTimeout) 中您会显示类名值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 2014-10-14
      相关资源
      最近更新 更多