rxjs内部的数据绑定是可观察到的

时间:2018-12-06 06:12:21

标签: angular rxjs observable

是否可以绑定到可观察内部的数据并在两个方向上维护数据?

例如:我有一个对话框,用户可以在其中输入某种数据。对话框的布局是从配置中加载的,位于可观察的内部。该配置包含将显示哪些输入字段。
因此,我尝试在对话框模板中使用async管道。渲染字段就像一种魅力一样,但是我尝试将数据绑定到可观察的内部值。每次关闭并打开对话框后,我都会得到一个新的可观察到的数据,并释放我的数据。

为避免丢失数据,我订阅了服务中的可观察对象并将其写入数据对象:

export class DataService implements OnInit {
  private data: any = {};
  ngOnInit() {
  this.http.get(path).subscribe((myData) => {
    this.data.data = myData;
  }
}

//other code ...

//opening the dialog this way
const dialogRef = this.dialog.open(MyDialogComponent, {
  width: '1200px',
  data: this.dataService.getData()
});

//Using data in the dialog template
<div *ngIf="data.data as myField; else loading">
  <mat-form-field>
    <input #inputText matInput 
      placeholder="{{ myField.name }}" 
      [(ngModel)]="myField.value" 
      name="{{ myField.name }}" 
      matTooltip="{{myField.description}}" 
      [required]="myField.required">
  </mat-form-field>
</div>
<ng-template #loading>
  <mat-spinner mode="indeterminate" diameter="30"></mat-spinner>
</ng-template>

我还可以从模型中分离数据,但这会使处理变得困难得多。

还有其他选项可以处理需求吗?最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

您是否考虑过在ReplaySubject中重新广播它?

export class DataService implements OnInit {
private data = new ReplaySubject<any>;
ngOnInit() {
this.http.get(path).subscribe((myData) => {
     this.data.next(myData);
    }
}

public getMyData()    {
     return Observable.of(this.myData);
 }

答案 1 :(得分:1)

使用shareReplay(1)是一种更清洁的解决方案,可使用async管道获取其值,其行为类似于BehaviourSubject。

export class DataService implements OnInit {
  private data: any = {};
  ngOnInit() {
  this.data.data=this.http.get(path).pipe(shareReplay(1))
}

//other code ...

//opening the dialog this way
const dialogRef = this.dialog.open(MyDialogComponent, {
  width: '1200px',
  data: this.dataService.getData()
});

<div *ngIf="(data.data | async) as myField; else loading">
  <mat-form-field>
    <input #inputText matInput 
      placeholder="{{ myField.name }}" 
      [(ngModel)]="myField.value" 
      name="{{ myField.name }}" 
      matTooltip="{{myField.description}}" 
      [required]="myField.required">
  </mat-form-field>
</div>
<ng-template #loading>
  <mat-spinner mode="indeterminate" diameter="30"></mat-spinner>
</ng-template>