登录表单中的 iOS 自动填充数据在cordova 应用程序中为空(使用角度)

Lin*_*nwe 7 forms login ios cordova angular

Cordova 8 / IOS 12 / Angular 6

我有一个带有登录表单的cordova 应用程序。除此之外,一切都运行良好。

在ios上,当用户在表单中聚焦时,苹果会提示用户输入保存的密码。当用户使用此 ios 自动填充功能时,表单不会检测到新值并且数据保持为空。(但用户可以看到出现在屏幕上的凭据)

这是我的登录表单:

 <form (ngSubmit)="login()" [formGroup]="loginForm">
        <input type="email" formControlName="username" name="username"/>
        <input type="password" formControlName="password" name="password"/>
        <button class="transparent-button primary">Login</button>
    </form>
Run Code Online (Sandbox Code Playgroud)

在我的组件中:

 constructor(
    /* ... */
 ) {
  this.loginForm = formBuilder.group({
    username: ["", Validators.required],
    password: ["", Validators.required]
  });

};

login(){
    //this.loginForm.value.username and 
    this.loginForm.value.password stay empty when user 
    autofill
}
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用模板驱动的表单:同样的问题。因此,Apple 现在阻止了我的应用程序的发布。这是 ios/cordova 的已知问题吗?

谢谢

小智 6

对于在 Ionic 5 中遇到过这个问题的人来说,这个修复解决了问题。我也在常规输入(而不是离子输入)上对此进行了测试。

显然,执行自动填充后,在没有焦点的输入字段上也会触发 Angular(更改)事件,这可以用于设置该表单字段的值。(如下所示):

<input ... (change)="form.controls[fieldName].setValue($event.target.value)">
Run Code Online (Sandbox Code Playgroud)

正如评论中所述,尽管 Ionic 3 存储库中提到了该修复,但使用该解决方案的用户(以及我自己)在 Ionic 5 中对其进行了测试。


jsp*_*iri 3

FWIW,我遇到了同样的问题,请参阅下面的解决方法。

我正在使用反应式表单,并且在登录表单上遇到了问题,其中我只输入了用户名和密码。我实现了一种解决方法,我订阅表单上的更改,然后检测本机密码值是否等于更改时的密码表单字段(技术上,更改后 500 毫秒等待自动填充输入密码值)。如果两者不同,我会使用触发表单验证的本机值手动覆盖表单值。

希望这对某人有帮助!

// login-form.component.ts

import { Component, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-login-form',
  template: require('./login-form.component.pug')(),
  styleUrls: ['./login-form.component.scss'],
})
export class LoginFormComponent {

  protected loginForm: FormGroup;

  @ViewChild('password') public passwordRef: ElementRef;

  constructor(private _formBuilder: FormBuilder) {
    this.loginForm = this.getForm();

    // NOTE: this hack triggers form validation on iOS autofill
    this.loginForm.valueChanges
      // wait for 500ms to be sure the autofill is finished with the password field
      .debounceTime(500)
      .subscribe((changes) => {
        // manually fetch the value from nativeElement
        let passVal = this.passwordRef.nativeElement.value; //(<HTMLInputElement>document.querySelector('[name="password"]')).value;
        // if the value saved in the form is different from the input, manually update it
        if (passVal !== changes.password) {
          this.loginForm.get('password').setValue(passVal);
        }
      })
    ;
    // NOTE: this hack triggers form validation on iOS autofill
  }

  protected getForm(): FormGroup {
    return this._formBuilder.group({
      username: ['', [
        Validators.required,
        Validators.email,
      ]],
      password: ['', [
        Validators.required,
      ]],
    });
  }

  public onSubmit(login: FormGroup) {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)
// login-form.component.pug
// NOTE: pug + bootstrap 4

h1 Login
form([formGroup]="loginForm", (ngSubmit)="onSubmit(loginForm)")
  .form-group
    input.form-control(
      formControlName="username",
      name="username",
      type="email",
      placeholder="Username",
      autocomplete="on",
      autocorrect="off",
      autocapitalize="off",
      spellcheck="false",
    )

  .form-group
    input.form-control(
      #password,
      formControlName="password",
      name="password",
      type="password",
      placeholder="Password",
      autocomplete="on",
      autocorrect="off",
      autocapitalize="off",
      spellcheck="false",
    )

  input.mb-3.btn.btn-lg(
    type="submit",
    value="Login",
    [class.btn-outline-primary]="loginForm.valid",
    [class.btn-outline-secondary]="!loginForm.valid",
    [disabled]="!loginForm.valid",
  )

Run Code Online (Sandbox Code Playgroud)