使用 NgRx 选择器为 Angular Reactive Form 设置默认值

Set default values for Angular Reactive Form using NgRx selector

我正在开发一个使用 Angular 和 NgRx 构建的应用程序。

我有一个反应式表单,我需要使用商店中的数据为一个表单控件设置默认值。

export class FormComponent implements OnInit {
 networks: Network[];
 form: FormGroup;

 ngOnInit(): void {
  this.form = this.fb.group({
    selectedNetworks: ['', [Validators.required]],
    ...
  });

  this.store.select(selectNetworks).subscribe(networks => {
   this.networks = networks;
   this.form.get('selectedNetworks').setValue(networks);
  });
}

<mat-select
  formControlName="selectedNetworks"
  multiple>

  <mat-option
    *ngFor="let n of networks"
    [value]="n">
     {{n.name}}
  </mat-option>
</mat-select>

如您所见,我有一个包含网络列表的多选。最初,应选择所有网络。

为了获得所有需要的网络,我需要发出几个http请求(这些是要求,不能更改)。每次成功请求后,ngrx 存储将更新并且 selectNetworks 选择器将发出一个新值。如果我需要发出 2 个请求来获取网络,选择器将 return 仅在第二次发射后所有网络。

还有一个 websocket 事件,它 return 是一个网络,以防它被更新(例如状态被改变)。在这种情况下,ngrx 存储将被更新并且 selectNetworks 选择器将再次发出。

我的问题是在以下情况下:初始化表单(选择所有网络),用户使其只选择一个网络,触发 websocket 事件,selectNetworks 执行订阅并再次选择所有网络,放弃用户所做的更改。

我做了一些研究,我看到了一些使用 take(1) 的解决方案。但是,这在我的情况下不起作用,因为第一次发射可能不包含完整的网络列表。 请问有没有适合我的解决方案?

提前致谢!

根据代码判断,我可以看到您正在用再次选择所有内容的商店状态覆盖控件的值。

这里有几个选项可以做什么,但基本上只有在没有值(未选择任何内容)的情况下,您才应该将整个数组分配给控件的值。如果选择了某些内容,则在商店有更新时重新使用它。

// update network array declaration
networks: Network[] = [];

this.store.select(selectNetworks).subscribe(networks => {
  this.networks = networks;
  const selected = this.form.get('selectedNetworks').getValue();

  const controlValue = selected.length > 0 ? selected : networks;  
  // or !!selected, not exactly sure what will getValue() return
  this.form.get('selectedNetworks').setValue(controlValue);
});