事件更改值时 ControlValueAccessor ngModel 未更新

问题描述

我有一个组件,它使用 controlvalueaccessor 绑定 ngModel 传递的表单父组件

password.component.ts:

     import {
  Component,ElementRef,forwardRef,HostListener,Input,OnChanges,OnInit,SimpleChanges
} from "@angular/core";
import { ControlValueAccessor,NG_VALUE_ACCESSOR } from "@angular/forms";
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => PasswordComponent),multi: true
};
@Component({
  selector: "app-password-input",templateUrl: "./password.component.html",styleUrls: ["./password.component.scss"]
})
export class PasswordComponent
  implements OnInit,ControlValueAccessor,OnChanges {
  _model: string;
  @input() depended: string = "";
  @input() name: string = "password";
  @input() id: string = "password";
  @input() class: string = "form-control";
  @input() placeholder: string = "";
  @input() required:boolean;

  setPassword(event) {
    this.writeValue(event);
  }

  changeModel() {
    this.model = "aaaa";
  }
 change(event){
    console.log("event",event);
    
  }
  constructor() {}
  ngOnChanges(changes: SimpleChanges): void {}
  ngOnInit(): void {}

  get model() {
    return this._model;
  }

  set model(val) {
    this._model = val;
    this.propagateChange(this._model);
  }

  writeValue(value: any) {
    if (value !== undefined) {
      this.model = value;
    }
  }

  propagateChange = (_: any) => {};

  registerOnChange(fn: any): void {
    this.propagateChange = fn;
  }

  registerOnTouched(fn: any): void {}

  setdisabledState?(isdisabled: boolean): void {}
}

和吹线是我的密码。component.html:

<div>
  <label for="password"
    >pass
    <small class="text-danger">*</small>
  </label>
  <div class="input-group mb-2">
    <input
      [class]="class"
      [id]="id"
      name="name"
      [(ngModel)]="model"
      #models="ngModel"
      (ngModelChange)="change($event)"
      [required]="required"
      [placeholder]="placeholder"
    />
    <div class="input-group-prepend">
      <button class="btn  rounded-0" (click)="changeModel()" type="button">
        change
      </button>
    </div>
  </div>
  in child component: {{model}}
</div>

以下是我的父组件:

<app-password-input [(ngModel)]='password' name="password" ngDefaultControl></app-password-input>
out:
{{password}}

我的问题是,当我使用触发密码组件中的 changeModel 模型的按钮更改输入时,正在更新但值不影响父组件中的 model.password

stack blitz link

解决方法

您需要向自定义组件提供 NG_VALUE_ACCESSOR 令牌才能正常绑定工作

@Component({
  selector: "app-password-input",templateUrl: "./password.component.html",styleUrls: ["./password.component.scss"],providers:[CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})

Forked Working Example