从ControlValueAccessor内部更新值时,值未反映在<input>中

时间:2019-08-14 11:39:35

标签: angular

我有一个表单控件myControl,已经在名为ControlValueAccessor的组件上实现了ControlComponent

AppComponent中,我有一个也绑定到myControl的输入

问题:

我在ControlComponent中有一个按钮,可以用表情符号替换当前值。当我单击该按钮时,表单可以很好地更新,但问题是该值未反映在input的{​​{1}}中

Stackblitz

1 个答案:

答案 0 :(得分:-1)

您需要将input标记移至ControlComponent。 将@Input(例如“ value”)添加到ControlComponent。 然后,您只需要更新value函数中的writeValue()就可以了。 作为组件父级的表单也已正确更新。

模板

<input [value]="value">
<button (click)="change('?')">
  set value: ?
</button>

ControlComponent

import { Component, OnInit, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-control',
  templateUrl: './control.component.html',
  styleUrls: ['./control.component.css'],
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => ControlComponent),
    multi: true,
  }]
})
export class ControlComponent implements ControlValueAccessor {
  @Input() value: string;
  onChange: (val: string) => void;
  onTouched: () => void;

  constructor() { }

  touch() {
    this.onTouched();
  }

  change(val: string) {
    this.onChange(val);
    this.value = val;
  }

  writeValue(value: string) {
    this.value = value;
    console.log(`write value ${value}`);
  }

  registerOnChange(fn: any) {
    this.onChange = fn;
    console.log('onChange')
  }

  registerOnTouched(fn: any) {
    this.onTouched = fn;
    console.log('onTouched')
  }

  setDisabledState() { }
}

AppComponent

<form [formGroup]="myForm">
  <app-control formControlName="myControl"></app-control>
</form>

<div>
    <span>Value: {{myForm.get('myControl').value}}</span>
</div>