2017-01-30 9 views
8

Я внедряю страницу входа с Угловыми реактивными формами. Кнопка «login» отключена, если форма недействительна.Угловая 2 и автозаполнение браузера

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 protected]", пароль: ""}', и в результате кнопка «login» отключена. Но если я щелкнул где-нибудь на странице, то он запустил onValueChanged, и я вижу '{имя_пользователя: "[email protected]", пароль: "123456"}', а кнопка "login" включена.

Если я иду в режиме инкогнито. У меня нет предварительно заполненных полей (они пусты), но когда я заполняю (выбираю) значения, то в консоли я вижу '{имя_пользователя: "[email protected]", пароль: "123456"}', а кнопка " login "включен без дополнительного клика.

Может быть, это разные события? Автозаполнение и автозаполнение? А угловые работы с ними по-разному?

Каков наилучший способ его решения? И почему onValueChanged Функция выполняется только один раз, когда поля автозаполнения браузера?

ответ

8

Проблема в браузере Chrome: он не позволяет получить доступ к значению поля пароля после автозаполнения (прежде чем пользователь нажимает на страницу). Таким образом, существует два способа:

  1. удалить проверку поля пароля;
  2. отключить автозаполнение пароля.
+0

Несчастливо автозаполнение пароля не работает. Пробовал все 3 возможных значения: 'autocomplete =" none | false | no "' – Denish

2

Я столкнулся с той же проблемой с 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 определен в модели представления, поскольку бизнес-логика строго отделена от представления в моем приложении.

UPDATE

С 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" /> 
-1

Я сделал Funtion

formIsValid(): boolean{ return this.form.valid; }

и чем добавить к кнопке:

<button [disabled]="!formIsValid()" type="submit">LogIn</button> 

Он работал для меня

0

Для полноты картины: У меня есть неактивная форма входа в системе. .

<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; 
    ... 

Таким образом, я могу получить доступ к значениям, предоставленным браузером, как только пользователь нажмет на . Вход.