如何在需要同步数据时正确使用RxJS Observable

时间:2017-06-07 10:02:51

标签: angular rxjs observable ngrx

希望主题或多或少可以理解。

我对RxJSRedux世界很陌生。我正在使用ObservablesNgRX store处理Angular 2+应用。

在店里,我有不同的部分。这里我需要的是从一个切片获取属性并将其传递给downloadService,该Array接受具有不同属性的AssetFile个自定义 constructor( private store: Store<AppState>, private downloadService: DownloadService) { this.selectedAssets$=this.store.select('selectedAssets') this.selectedAssets$.subscribe(asset => this.assetsSelected = asset) } 个对象。

assetFiles

不确定我是否正确地做了那部分。在UI中,一旦选择了一个Asset,它就会调度到Store.selectedAssets。在这里,我将它分配给this.selectedAssets $并创建另一个变量this.assetsSelected,它假设是这些选定对象的数组。

然后我有这个功能来准备&#34;文件供下载。每个资产都有属性File[],其类型为Array,最后我只需 prepareFilesToDownload(){ let files = [] let preparedFiles = this.assetsSelected.map(asset => { asset.assetFiles.map(file=>{ files.push(file) }) }) return files } 个文件。

Observable

此代码有效,但我认为这不是正确的做事方式。我刚刚失去了一点。

我可以使用更少的代码并直接从this.selectedAssets$=this.store.select('selectedAssets') constructor( private store: Store<AppState>, private downloadService: DownloadService) { this.selectedAssets$=this.store.select('selectedAssets') }

获得此结果

更新:

flatten

在这里,我使用Ramda中的 prepareFilesToDownload(){ let files this.selectedAssets$.subscribe( assets => { files = R.flatten(assets.map(asset => asset.assetFiles.map(file => file))) } ).unsubscribe(); return files } 方法将数组数组合并为单个数组。

this.selectedAssets$

看起来好一点,但仍然不确定它是否适合使用Observables。我认为更好的方法是直接使用RxJS运算符从.subscribe observable返回此数组。但是找不到正确的方法。

一方面的问题。如第二个示例中的.unsubscribe.take(1)是正确的,还是我可以使用class Batch(models.Model): material_id = models.ManyToManyField(AssetMetadata) user = models.ForeignKey(User) def __str__(self): return 'Batch_' + str(self.pk) + '_' + self.user.username class AssetMetadata(models.Model): material_id = models.CharField(max_length=256, blank=True) series_title = models.CharField(max_length=256, blank=True) season_title = models.CharField(max_length=256, blank=True) season_number = models.IntegerField(default=0) episode_title = models.CharField(max_length=256, blank=True) episode_number = models.IntegerField(default=0) synopsis = models.TextField(max_length=1024, blank=True) ratings = models.CharField(max_length=256, blank=True) def __str__(self): return self.material_id 代替?

1 个答案:

答案 0 :(得分:1)

我认为你的第二个选择要好得多,你当场就删除局部变量和订阅。如果我正确使用它,一旦用户选择“下载”(或对文件执行某些操作),您就可以使用获取文件和处理。在这种情况下,为什么不在一个地方触发整个链?

this.selectedAssets$
  .map(this.prepareFiles)
  .do(this.downloadFiles) // or process files
  .take(1)
  .subscribe(); // you must do this to make the observable hot

这也与unsubscribe有关。不确定它是否有效,即使它确实如此,它的可读性和标准也不如take(1)