Angular 2 및 브라우저 자동 채우기
저는 Angular reactive 형태의 로그인 페이지를 구현하고 있습니다.양식이 올바르지 않으면 "로그인" 단추가 비활성화됩니다.
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" 및 "passwords" 필드가 미리 채워집니다.그리고 콘솔에서 '{userName: "email@email.com ", 암호: " }', 결과적으로 "filename" 버튼이 비활성화되었습니다.그러나 페이지의 어딘가를 클릭하면 ValueChanged에서 트리거되고 '{userName: "email@email.com ", 암호: "123456" } 및 버튼 "filename"이 활성화됩니다.
제가 몰래 가면.필드가 미리 채워지지 않았지만 값을 입력(선택)하면 콘솔에 '{userName: "email@email.com ", 암호: "123456" }, 추가 클릭 없이 "filename" 버튼이 활성화됩니다.
그것들은 다른 이벤트일 수도 있습니까?자동 채우기 및 자동 완성?각도는 그들과 다르게 작용합니까?
그것을 해결하는 가장 좋은 방법은 무엇입니까?그리고 브라우저 자동 채우기 필드에서 onValueChanged 함수가 한 번만 실행되는 이유는 무엇입니까?
Chrome 브라우저의 문제: 사용자가 페이지를 클릭하기 전에 자동 입력 후 암호 필드의 값에 액세스할 수 없습니다.두 가지 방법이 있습니다.
- 암호 필드의 유효성 검사를 제거합니다.
- 암호 자동 완성을 비활성화합니다.
당신이 사용할 수 있다는 것을 알게 되었습니다.autocomplete="new-password"
여기에 설명된 바와 같이
이렇게 하면 암호 필드가 자동으로 채워지지 않습니다. 이것이 바로 저의 경우입니다.위의 링크에서 사용할 수 있는 다른 많은 자동 완성 특성이 있습니다.
이것은 나에게 효과가 있습니다.
before(자동 채우기)
<div class="form-group form-row required">
<input class="input p-l-20 form-control" formControlName='otp' type="text" name="otp" placeholder="Enter OTP">
</div>
after(자동 충전이 안 됨, 정상 작동)
<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>
참고 숨기기는 부트스트랩 v4 클래스입니다.
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" />
도움이 되길 바랍니다.
참고:vm
에 정의되어 있습니다.UIComponentBase
뷰 모델을 참조합니다.SigninViewModel
내 구성 요소의. 그FormGroup
인스턴스는 비즈니스 로직이 애플리케이션의 뷰와 엄격하게 분리되므로 뷰 모델에 정의됩니다.
갱신하다
v59부터 필드 자동 완료 시 입력의 포커스 이벤트가 발생하는 것 같습니다.따라서 위의 해결 방법은 더 이상 작동하지 않습니다.다음은 시간 초과를 사용하여 필드가 자동 완료 또는 사용자에 의해 업데이트되는지 여부를 확인하는 업데이트된 해결 방법입니다.
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;
setTimeout(
() =>
{
this._autofillChrome = false;
},
250 // 1/4 sec
);
this.vm.FormGroup.valueChanges.subscribe(
(data) =>
{
if (this._autofillChrome && data.uname)
{
this._password = " ";
this._autofillChrome = false;
}
});
}
}
//--------------------------------------------------------------------------------------------
// PROPERTIES
//--------------------------------------------------------------------------------------------
private _password: string;
private _autofillChrome: boolean;
}
그리고 내 html에는:
<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" />
해결 방법을 찾았습니다.
일부 varisDisabled 생성: 부울 = false UPDATE: 1.1 하나 더 - var initCount: number = 0;
ngOnInit(): void { this.isDisabled = false; this.initCount++; }
메서드 만들기
코드는 다음과 같습니다.
// 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;
}
}
- 다음과 같은 방법으로 html을 업데이트합니다.
여기 HTML의 샘플이 있습니다.
<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>
완전성을 위해:응답하지 않는 로그인 양식이 있습니다.
<form name="loginForm" role="form" (ngSubmit)="onLoginSubmit()">
<input name="username" #usernameInp>
<input type="password" name="password" #passwordInp>
<button type="submit">Login</button>
</form>
사용할 경우[(ngModel)]="username"
변수username
브라우저 자동 채우기 기능이 시작되면 관련 구성 요소가 채워지지 않습니다.
따라서 대신 ViewChild로 작업합니다.
@ViewChild('usernameInp') usernameInp: ElementRef;
@ViewChild('passwordInp') passwordInp: ElementRef;
...
onLoginSubmit() {
const username = this.usernameInp.nativeElement.value;
const password = this.passwordInp.nativeElement.value;
...
이렇게 하면 사용자가 로그인을 클릭하면 브라우저에서 제공하는 값에 액세스할 수 있습니다.
나의 솔루션 2019 버전:기스트 허브
// <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;
이거 한번 해보세요.잠시 머리를 쥐어짜긴 했지만 이것이 효과가 있었습니다.
input:-webkit-autofill {
-webkit-transition-delay: 99999s;
}
속성을 추가하여 이 문제를 해결했습니다.autocomplete="new-feildName"
태그를 입력합니다.
예:
<input type="text" class="mr-input" formControlName="email"
placeholder="Adresse e-mail" autocomplete="new-email"/>
참고: 모든 필드에 자동 완성을 추가해야 합니다.
나는 기능을 만들었습니다.
formIsValid(): boolean{ return this.form.valid; }
단추에 추가하는 것보다 더 중요합니다.
<button [disabled]="!formIsValid()" type="submit">LogIn</button>
저한테는 효과가 있어요.
언급URL : https://stackoverflow.com/questions/41932810/angular-2-and-browser-autofill
'programing' 카테고리의 다른 글
CSS - Overflow: Scroll; - 항상 수직 스크롤 막대를 표시합니까? (0) | 2023.07.31 |
---|---|
선행 0을 추가하는 방법은 무엇입니까? (0) | 2023.07.31 |
dplyr을 사용하여 테이블의 모든 행에 함수를 적용하시겠습니까? (0) | 2023.06.22 |
VSCode의 현재 변경 사항을 한 번에 모두 수용하려면 어떻게 해야 합니까? (0) | 2023.06.22 |
데이터 프레임에서 이름별로 열을 삭제하는 방법 (0) | 2023.06.21 |