首页 > 解决方案 > Angular 反应式输入控件中不同模型和视图值的简单解决方案

问题描述

我有一个formControlwith 值设置为 object like {id: 1, name: 'Ramesh'}。mat-form-field 中的输入字段是只读的,值来自数据库或从选择列表中选择。

为了显示不同的视图值,我使用[value]如下绑定。当用户稍后更新控件时,它会正确显示。但是当它第一次用保存的值初始化时,它的显示[object Object]

在内部,它取决于执行DefaultValueAccessor writeValue method[value]绑定的顺序。

https://stackblitz.com/edit/angular-ivy-mkvx8a?file=src%2Fapp%2Fapp.component.ts

<input readonly [formControl]="userControl" [value]="userControl.value?.name">

我想创建自定义值访问器,但似乎太多了。

标签: angularangular-materialangular-reactive-forms

解决方案


我通过扩展DefaultValueAccessor和提供自定义writeValue方法解决了这个问题。但我觉得 Angular 应该为自定义方法提供一种writeValue方法。

例如垫自动完成displayWith

演示: https ://stackblitz.com/edit/angular-ivy-mkvx8a?file=src%2Fapp%2Fapp.component.html

<input valueKeyAccessor [formControl]="control">
@Directive({
  selector: "input[valueKeyAccessor]",
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => valueKeyAccessor),
      multi: true
    }
  ]
})
export class valueKeyAccessor extends DefaultValueAccessor {
  @Input("valueKeyAccessor") propToDisplay;

  writeValue: any;
  constructor(
    _renderer: Renderer2,
    _elementRef: ElementRef,
    @Optional() @Inject(COMPOSITION_BUFFER_MODE) _compositionMode: boolean
  ) {
    // Refer signature from https://github.com/angular/angular/blob/9.1.11/packages/forms/src/directives/default_value_accessor.ts#L36-L156
    super(_renderer, _elementRef, _compositionMode);
    // overwriting the writeValue    
    this.writeValue = value => {
      value = value && value[this.propToDisplay];
      const normalizedValue =
        (value === undefined || value === null) ? "" : value;
      super.writeValue(normalizedValue);
    };
  }

  ngOnInit() {
    this.propToDisplay = this.propToDisplay || "name";
  }
}

推荐阅读