ControlValueAccessor不适用于另一个组件中的一个组件

时间:2019-05-14 00:43:20

标签: angular

我正在实现 ControlValueAccessor 接口,以将组件转换为自定义表单控件。

我有一个封装了本地表单控件(例如输入:文本)的组件,并且可以直接在表单中完美地工作。

我有另一个组件封装了第一个组件,并且还实现了ControlValueAccessor接口。但是,当我尝试使用此组件时,它不会将值传递给第一个组件,只有在更改时才能获取它。

我不明白为什么它不起作用,因为我想象Angular应该将我的第一个组件识别为输入的表单控件,但是尽管它可以识别形式,但不能在另一个组件中识别它。

这是说明我问题的代码。

internal-control.component.ts

export const DEFAULT_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => InternalControlComponent),
  multi: true,
};

@Component({
  selector: 'app-internal-control',
  template: `<input type="text" ngDefaultControl>`,
  providers: [ DEFAULT_VALUE_ACCESSOR ],
})
export class InternalControlComponent implements ControlValueAccessor {
  @ViewChild(DefaultValueAccessor) private valueAccessor: DefaultValueAccessor;

  writeValue(value: any): void {
    this.valueAccessor.writeValue(value);
  }
  registerOnChange(fn: any): void {
    this.valueAccessor.registerOnChange(fn);
  }
  registerOnTouched(fn: any): void {
    this.valueAccessor.registerOnTouched(fn);
  }
  setDisabledState?(isDisabled: boolean): void {
    this.valueAccessor.setDisabledState(isDisabled);
  }
}

external-control.component.ts

export const DEFAULT_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => ExternalControlComponent),
  multi: true,
};

@Component({
  selector: 'app-external-control',
  template: `<app-internal-control type="text" ngDefaultControl></app-internal-control>`,
  providers: [ DEFAULT_VALUE_ACCESSOR ],
})
export class ExternalControlComponent implements ControlValueAccessor {
  @ViewChild(DefaultValueAccessor) private valueAccessor: DefaultValueAccessor;

  writeValue(value: any): void {
    this.valueAccessor.writeValue(value);
  }
  registerOnChange(fn: any): void {
    this.valueAccessor.registerOnChange(fn);
  }
  registerOnTouched(fn: any): void {
    this.valueAccessor.registerOnTouched(fn);
  }
  setDisabledState?(isDisabled: boolean): void {
    this.valueAccessor.setDisabledState(isDisabled);
  }
}

app.component.ts

@Component({
  selector: 'app-root',
  template:
  `
    <p>Internal control (it works)</p>
    <app-internal-control [(ngModel)]="value" name="a"></app-internal-control>
    <p>External control (doesn't work)</p>
    <app-external-control [(ngModel)]="value" name="b"></app-external-control>
    <p>Value:</p>
    <span>"{{value}}"</span>
  `,
})
export class AppComponent {
  value = 'initial value';
}

0 个答案:

没有答案