Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度2和浏览器自动填充_Angular_Typescript_Autocomplete_Autofill - Fatal编程技术网

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>
    

    这样,一旦用户单击登录,我就可以访问浏览器提供的值。

    我找到了一些解决方法

  • 创建一些变量已禁用:boolean=false 更新: 1.1还有一件事-var initCount:number=0

    ngOnInit():void{ this.isDisabled=false; 这个.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;
        }
      }
    
    //此方法将被称为异步
    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;
    }
    }
    
  • 使用以下内容更新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>
    
    
    {{'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”
    @Denish
    autocomplete=“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;