【问题标题】:Data binding inside rxjs observablerxjs observable 内部的数据绑定
【发布时间】:2019-05-07 19:21:52
【问题描述】:

是否可以绑定到可观察对象内的数据并双向维护数据?

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

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

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>

我也可以从我的模型中分离数据,但这会使处理变得更加困难。

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

【问题讨论】:

    标签: angular rxjs observable


    【解决方案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>
    

    【讨论】:

      【解决方案2】:

      你有没有想过在 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);
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-17
        • 2017-12-17
        • 1970-01-01
        • 2020-05-25
        • 2022-08-06
        • 2021-06-14
        • 2020-09-01
        • 1970-01-01
        相关资源
        最近更新 更多