Angular 2 - 浏览器自动填充时表单无效

问题描述 投票:0回答:9

我有一个登录表单,其中包含电子邮件和密码字段。

我选择了浏览器自动填充。

问题是:当浏览器自动填充登录表单时,两个字段都是原始且未受影响的,因此提交按钮被禁用。

如果我单击禁用按钮,它会启用并触发提交操作,这很好。但默认禁用的方面非常糟糕,这可能会让一些用户感到失望。

你有什么应对的办法吗?

angular angular2-forms
9个回答
6
投票

我还通过检查显示错误消息时是否触摸了表单来解决了这个问题。 例如,提交按钮看起来像这样

<input type="submit" class="btn btn-default" [disabled]="loginFormGroup.invalid && loginFormGroup.touched" />

4
投票

我似乎只通过模拟页面上的点击就解决了这个问题

AfterViewInit

杰斯:

public ngAfterViewInit(): void {
    document.querySelector('body').click();
}

使用 JQuery :

public ngAfterViewInit(): void {
    $('body').click();
}

Chrome 67.0.3396.99、Angular 5.1.0


2
投票

我通过

ChangeDetectorRef
提供商解决了这个问题。
在检查输入是否有效之前,只需执行手动
detectChanges()
即可。

如果单击按钮后无法检查,请使用事件绑定

(input)=changedetectorfunc()
收听输入元素的输入事件,并在此函数中调用
changeDetector

因此它必须有效。
希望对你有帮助。

有用的链接:

最美好的祝愿


0
投票

有两种方法可以解决这个问题

  • 使用CSS伪类-webkit-autofill它将检测自动填充。

https://developer.mozilla.org/en-US/docs/Web/CSS/:aut

  • 使用 Angular/cdk 模块中的 AutofillMonitor 包,该包可以对验证器进行猴子修补,因为 requiredValidator 无法确认自动填充输入。

https://gist.github.com/kherock/fad4c320c5894ec68373588e338955c5


0
投票

解决方案

当您查看表单页面源代码中的字段(例如登录用户名输入字段)时 - 您是否看到一个名为“cdk-text-field-autofilled”的类。

我不太了解这个 cdk 现场监控是否所有角度应用程序都使用它,但我今天正在从事的项目已经使用它。

<input _ngcontent-vio-c24="" class="mat-input-element mat-form-field-autofill-control cdk-text-field-autofill-monitored cdk-text-field-autofilled ng-dirty ng-valid ng-touched" formcontrolname="username" id="username" matinput="" placeholder="Username" aria-invalid="false" aria-required="false">

因此,如果对任何人有用,即您有此类或类似的表示自动填充的内容,这就是我所做的:

HTML

将 #username 添加到输入字段(如果尚未存在):

<input matInput placeholder="{{'labels.Logon.Username' | translate}}" formControlName="username" id="username" #username>

向按钮 [禁用] 添加了规则或其他规则 - new && notAutofilled 在我的项目中,其他 2 个已经存在:

 [disabled]="(loginForm.invalid || loggingIn) && notAutofilled"

打字稿

添加了相关导入“ViewChild、ElementRef、AfterViewInit”(如果尚未存在):

import {Component, Input, OnInit, ViewChild, ElementRef, AfterViewInit, OnDestroy} from '@angular/core';

添加导出类AfterViewInit:

export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {

添加变量:

@ViewChild('username') userName: ElementRef;
public notAutofilled = true;

在 SetTimeOut 上创建 ngAfterViewInit:

ngAfterViewInit(){
    setTimeout(() => {
    if (this.userName.nativeElement.classList.contains('cdk-text-field-autofilled')) {
        this.notAutofilled = false;   
    }
    else{console.log("Not Autofilled");}
    }, 500);
  }

-2
投票

我也有同样的问题。

我通过以下方式解决了这个问题: - 删除组件中密码字段的

Validators.required
验证器 - 在模板中的标签处使用
<input ... required ...>
指令


-2
投票

这不是代码的最佳实践,但它肯定会起作用 -

如果您有双向绑定,那么它的任务非常简单,只需检查两个文本框的长度,如果它大于零,则返回 false,否则返回 true 并调用禁用属性中的方法。 方法-

    validcheck() {
         return username.length <= 0 || password.length <= 0;     
    }

并调用按钮禁用属性内的方法

    <button [disabled]="validcheck()">Submit</button>

-3
投票

也遇到同样的问题。我不确定这是否是最好的方法,但我可以通过添加 AfterViewChecked 来使其工作

import { Component, AfterViewChecked } from "@angular/core";

export class LoginComponent implements AfterViewChecked {
    // Beware! Called frequently!
    // Called in every change detection cycle anywhere on the page
    ngAfterViewChecked() {
        console.log(`AfterViewChecked`);
        if (this.usr.userName) {
            // enable to button here.
            console.log("found username in AfterViewChecked");
        }
    }
}

或者你也许可以尝试 Angular2 的其他 Lifecycle Hooks https://embed.plnkr.co/?show=preview


-3
投票

根据官方文档

"pristine" means the user hasn't changed the value since it was displayed in this form

因此,如果您的表单中有验证,这是检查表单是否“有效”或“无效”的更好方法

<button [disabled]="formName.invalid">Submit</button>

所以形式是否原始并不重要。

© www.soinside.com 2019 - 2024. All rights reserved.