【问题标题】:Angular - Unable to set default value from inside a component when using ControlValueAccessorAngular - 使用 ControlValueAccessor 时无法从组件内部设置默认值
【发布时间】:2017-05-18 18:58:14
【问题描述】:

演示:https://plnkr.co/edit/cMu3lI3PkxHRErJE3T93?p=preview

我有一些组件似乎都有相同的问题,那就是我无法在使用ControlValueAccessor 时为ngModelformControlName 设置默认值。

例如,在演示中,我们有一个提供更好的 UX 和视觉效果的选择,但在 ngOnInit 中,如果选择具有 required 输入集,我无法将模型设置为提供的选项中的第一项到true

如果true,则选择将始终有一个值。但是现在它仅在您实际单击选项后才起作用。

一个“解决方案”是始终在使用它的父级中设置该值。但这需要大量不必要的代码,我不想这样做。尤其是因为设置默认值应该不是问题。

所以这里是我们正在使用的一个简短的 sn-p:

  private _model: any;

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

  get model() {
    return this._model;
  }

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

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

  registerOnTouched() {}

  writeValue(value: any) {

    if (value !== undefined) {
      this.model = value;
      this.cd.markForCheck();
    }
  }

  ngOnInit() {

    if (!this.model && this.required) {
      this.model = this.options[0];
    }
    else if (!this.required) {
      this.model = null;
    }

    this.propagateChange(this.model);
  }

正如您在演示中看到的那样,ngOnInit 中的模型设置不起作用。

这是为什么?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    当您调用this.propagateChange(this.model); 时,此功能尚未注册。

    所以我知道两种解决方法

    1) 分配propagateChange 后更新模型

    export const NOOP: any = () => {};
    ...
    
    propagateChange = NOOP;
    
    registerOnChange(fn: () => any) {
      this.propagateChange = fn;
      if(this.required) {
        fn(this.model);
      }
    }
    
    writeValue(value: any) {
      if (value !== undefined && this.propagateChange !== NOOP) {
        this.model = value;
        this.cd.markForCheck();
      }
    }
    

    Plunker Example

    2) 使用ngModelChange 事件

    @Output() ngModelChange = new EventEmitter();
    
    this.ngModelChange.emit(this.model);
    

    Plunker Example

    【讨论】:

    • 已经测试了 ngModelChange 的东西,这太可怕了,它会在某些无法设置实际值的情况下中断。所以我会从答案中删除它:) 另一个解决方案似乎有效,但你必须“解决”它才能让这么简单的事情起作用,这似乎很奇怪。但现在我会接受它。谢谢。
    • 实际上这个解决方案也不允许设置实际值,它总是将其设置为选项的第一个值。见plnkr.co/edit/IcaPj582CeLzzsSMqhmE?p=preview
    • 什么意思?你能重现它吗?
    • 请参阅上面评论中的 plunkr。我在 app 组件的构造函数中设置了值,但它仍然给了我传入的选项的第一个值。
    • sortBy = this.options[0];?我没有看到任何构造函数
    猜你喜欢
    • 2017-03-27
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多