Angular 角度2和浏览器自动填充
我正在用表单实现登录页面。如果表单无效,则禁用“登录”按钮Angular 角度2和浏览器自动填充,angular,typescript,autocomplete,autofill,Angular,Typescript,Autocomplete,Autofill,我正在用表单实现登录页面。如果表单无效,则禁用“登录”按钮 import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'signin', templateUrl: './signin.component.html' }) export class Sig
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'signin',
templateUrl: './signin.component.html'
})
export class SignInComponent implements OnInit {
private signInForm: FormGroup;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.buildForm();
}
private buildForm(): void {
this.signInForm = this.formBuilder.group({
userName: ['', [Validators.required, Validators.maxLength(50)]],
password: ['', [Validators.required, Validators.maxLength(50)]]
});
this.signInForm.valueChanges
.subscribe((data: any) => this.onValueChanged(data));
this.onValueChanged();
}
private onValueChanged(data?: any) {
console.log(data);
}
所以,当我在浏览器中启动它时,我已经预先填充了“用户名”和“密码”字段。在控制台中,我有值“{userName:”email@email.com,密码:“}”,因此按钮“登录”被禁用。但若我点击页面上的某个地方,它会触发值更改,我会看到“{userName:”email@email.com,密码:“123456”},并启用“登录”按钮
如果我进入匿名模式。我没有预填充的字段(它们是空的),但当我填充(选择)值时,在控制台中我会看到“{userName:”email@email.com,密码:“123456”}和按钮“登录”已启用,无需额外单击
也许它们是不同的事件?自动填充和自动完成?angular与他们的工作方式不同
解决这个问题的最佳方法是什么?为什么浏览器自动填充字段时,onValueChanged功能只执行一次?Chrome浏览器中的问题:在自动填充后(用户单击页面之前),它不允许访问密码字段的值。因此,有两种方法:
我在Chrome v58.0.3029.96上也遇到了同样的问题。以下是我保持验证和自动完成的变通方法:
export class SigninComponent extends UIComponentBase
{
//--------------------------------------------------------------------------------------------
// CONSTRUCTOR
//--------------------------------------------------------------------------------------------
constructor(viewModel: SigninViewModel)
{
super(viewModel);
// Autofill password Chrome bug workaround
if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
{
this._autofillChrome = true;
this.vm.FormGroup.valueChanges.subscribe(
(data) =>
{
if (this._autofillChrome && data.uname)
{
this._password = " ";
this._autofillChrome = false;
}
});
}
}
//--------------------------------------------------------------------------------------------
// PROPERTIES
//--------------------------------------------------------------------------------------------
private _password: string;
private _autofillChrome: boolean;
//--------------------------------------------------------------------------------------------
// COMMAND HANDLERS
//--------------------------------------------------------------------------------------------
private onFocusInput()
{
this._autofillChrome = false;
}
}
在我的html中:
<input mdInput
[placeholder]="'USERNAME_LABEL' | translate"
[formControl]="vm.FormGroup.controls['uname']"
(focus)="onFocusInput()" />
[...]
<input mdInput
type="password"
[placeholder]="'PASSWORD_LABEL' | translate"
[formControl]="vm.FormGroup.controls['password']"
(focus)="onFocusInput()"
[(ngModel)]="_password" />
<input mdInput
[placeholder]="'USERNAME_LABEL' | translate"
[formControl]="vm.FormGroup.controls['uname']" />
[...]
<input mdInput
type="password"
[placeholder]="'PASSWORD_LABEL' | translate"
[formControl]="vm.FormGroup.controls['password']"
[(ngModel)]="_password" />
在我的html中:
<input mdInput
[placeholder]="'USERNAME_LABEL' | translate"
[formControl]="vm.FormGroup.controls['uname']"
(focus)="onFocusInput()" />
[...]
<input mdInput
type="password"
[placeholder]="'PASSWORD_LABEL' | translate"
[formControl]="vm.FormGroup.controls['password']"
(focus)="onFocusInput()"
[(ngModel)]="_password" />
<input mdInput
[placeholder]="'USERNAME_LABEL' | translate"
[formControl]="vm.FormGroup.controls['uname']" />
[...]
<input mdInput
type="password"
[placeholder]="'PASSWORD_LABEL' | translate"
[formControl]="vm.FormGroup.controls['password']"
[(ngModel)]="_password" />
[...]
我做了一个动作
formIsValid():布尔值{
返回此.form.valid;
}
然后添加到按钮:
<button [disabled]="!formIsValid()" type="submit">LogIn</button>
登录
为了完整起见,它对我有用:我有一个非反应性的登录表单
<form name="loginForm" role="form" (ngSubmit)="onLoginSubmit()">
<input name="username" #usernameInp>
<input type="password" name="password" #passwordInp>
<button type="submit">Login</button>
</form>
这样,一旦用户单击登录,我就可以访问浏览器提供的值。我找到了一些解决方法
// This method will be called async
onStart(): Observable<boolean> {
if (this.loginFomrControl.hasError('required') &&
this.passwordFormControl.hasError('required') && this.initCount == 1) {
this.isDisabled = false;
// increase init count so this method wound be called async
this.initCount++;
}
return new BehaviorSubject<boolean>(true).asObservable();
}
// This method will ve called on change
validateForm() {
if (this.loginFormControl.value != '' && this.passwordFormControl.value != '') {
this.isDisabled = false;
} else if (this.loginFomrControl.value == '' || this.passwordFormControl.value == '') {
this.isDisabled = true;
}
}
//此方法将被称为异步
onStart():可观察{
if(this.loginfomrc.hasrerror('required')&&
this.passwordFormControl.hasError('required')&&this.initCount==1){
this.isDisabled=false;
//增加init count,以便将此方法称为async
这个.initCount++;
}
返回新的BehaviorSubject(true).asObservable();
}
//此方法将调用更改
validateForm(){
if(this.loginFormControl.value!=''&&this.passwordFormControl.value!=''){
this.isDisabled=false;
}else if(this.loginfomrc.value=''| | this.passwordFormControl.value=''){
this.isDisabled=true;
}
}
<div class="container" *ngIf="onStart() | async">
<!-- Do Stuff -->
<mat-form-field class="login-full-width">
<input matInput placeholder="{{ 'login_email' | translate }}" id="login_email" [formControl]="loginFomrControl" (change)="validateForm()">
<mat-error *ngIf="loginFomrControl.hasError('email') && !loginFomrControl.hasError('required')">
{{'login_email_error' | translate}}
</mat-error>
<mat-error *ngIf="loginFomrControl.hasError('required')">
{{ 'login_email' | translate }}
<strong>{{ 'login_required' | translate }}</strong>
</mat-error>
</mat-form-field>
<!-- Do Stuff -->
</div>
{{'login_email_error'{124; translate}}
{{‘登录(电子邮件|翻译}}
{{'login_required'| translate}}
我发现您可以使用autocomplete=“新密码”
如所述
这样,您的密码字段将不会自动填充,这就是我的情况。
在上面的链接中还有许多其他的自动完成属性。这对我来说很有用
1。之前(自动填充)
2。之后(现在不是自动填充,工作正常)
注意隐藏是引导v4类
试试这个。我绞尽脑汁想了一会儿,但这成功了
input:-webkit-autofill {
-webkit-transition-delay: 99999s;
}
我的解决方案2019版本:
//
//
修复自动填充(事件,类型){
常量值=event.target.value;
如果(类型=='username'){
this.loginForm.patchValue({
用户名:value
},{emitEvent:true,onlySelf:false});
}否则{
this.loginForm.patchValue({
密码:value
},{emitEvent:true,onlySelf:false});
}
//console.log('after click',this.loginForm.value);
}
@ViewChild('usernameInput')usernameInput:InInput;
@ViewChild('passwordInput')passwordInput:Input;
不幸的是,密码自动完成似乎不起作用。尝试了所有3种可能的值:autocomplete=“none | false | no”
@Denishautocomplete=“off”
如果我们从chrome中启用保存密码弹出窗口,则autocomplete=“off”不起作用autocomplete=“off”将要求第一次保存凭据,如果用户选择,则下次自动完成=“off”不起作用,您将看到凭据已填充。我发现使用autocomplete=“new password”可以防止chrome自动填充。
<div class="form-group form-row required">
<input class="input p-l-20 form-control" formControlName='otp' type="text" name="otp" placeholder="Enter OTP">
<!-- this dummy input is solved my problem -->
<input class="hide" type="text">
</div>
input:-webkit-autofill {
-webkit-transition-delay: 99999s;
}
// <ion-input (change)="fixAutoFill($event, 'password')" #passwordInput autocomplete="off" formControlName="password" type="password"></ion-input>
// <ion-input (change)="fixAutoFill($event, 'username')" #usernameInput autocomplete="off" type="text" formControlName="username"></ion-input>
fixAutoFill(event, type) {
const value = event.target.value;
if (type === 'username') {
this.loginForm.patchValue({
username: value
}, {emitEvent: true, onlySelf: false});
} else {
this.loginForm.patchValue({
password: value
}, {emitEvent: true, onlySelf: false});
}
// console.log('after click', this.loginForm.value);
}
@ViewChild('usernameInput') usernameInput: IonInput;
@ViewChild('passwordInput') passwordInput: IonInput;