Angular 2无法为ControlValueAccessor组件设置默认值。

9

缩小后的plunkr:https://plnkr.co/edit/gGCiYjcq70xaewn3n22F?p=preview

@Input() model: any;

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

registerOnChange(fn) {
  this.propagateChange = fn;
}

registerOnTouched() {}

writeValue(value: any) {

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

ngOnInit() {

  // Sets the model properly, but it doesn't show up in the view or outside of the component
  if (!this.model && this.isRequired) {
    this.model = options[0];
  }

  this.propagateChange(this.model);
}

使用方法:

<form #myForm="ngForm">
  <custom-select #fuel="ngModel" [(ngModel)]="model.fuel" [options]="fuels" [isRequired]="true" name="fuel"></custom-select>
</form>

我已经为自定义选择器实现了ControlValueAccessor,但是当组件在ngOnInit方法中首次初始化时,无法设置默认值。虽然model在组件内部正确设置,但它在视图或组件外部不反映。但如果我通过选择其他选项来更改值,它就会起作用.. 有谁知道这是为什么吗?


我猜这是一个变更检测问题,因为ngOnInit()是从变更检测中调用的。但我不知道如何修复它。 - Günter Zöchbauer
@GünterZöchbauer 这真是个糟糕的事情。让这个工作起来真的很重要,嗯...如果你碰巧找到了解决方案,我会给你一个丰厚的奖励。在那之前,我想我只能尝试一切可能的方法了... - Chrillewoodz
我对表单没有深入的了解。或许有其他人可以帮忙。 - Günter Zöchbauer
我猜你应该在writeValue方法内设置默认值。https://plnkr.co/edit/k6WpY4ERzH3fZ2QgZIz2?p=preview 因为writeValue总是从NgModel组件触发,并且它会在你的组件中的ngOnInit之后发生。你还可以看到我如何通过setter属性(@Input() set model(val))检查模型。 - yurzui
1
registerOnChange函数在控件初始化后运行。因此,在ngOninit中,propagateChange函数仍然是(_: any) => {},没有任何影响。 - yurzui
显示剩余2条评论
2个回答

3

我写了@Input('ngModel') model: any;,这样正确吗?如果我不这样做,我就不明白如何将model<custom-select [(ngModel)]="test"></custom-select>中的ngModel连接起来。因为我已经添加了ControlValueAccessor,所以输入不再是model,这意味着组件中对于this.model的任何检查理论上都不应该工作,因为现在输入是ngModel。所以使用@Input() model: any;,我不明白它仍然可以工作的原因。 - Chrillewoodz

3

我认为这是最简洁的方法:

registerOnChange(fn: any): void {
  this.propagateChange = fn;
  if (this.value == null) {
   this.propagateChange('defautlValue');
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接