无法将数据从ngrx存储渲染到组件

时间:2017-10-04 15:51:11

标签: angular ngrx

我正在使用ngrx和angular。 我有一个组件,其中有一个下拉模块' A'。在更改下拉列表时,我在我的ngrx商店中设置了所选值。

现在我在模块中有一个网格组件' B'。我的任务是用一个数据集填充网格(根据保存的下拉列表ID进行过滤)。

我可以在沙盒中获取数据集。这个sandox只是一个图层黑白组件和存储

public getAllDevices(): Observable<Array<Device>> {
    return this.appStateManager.getFromStore(state => state.serviceProviderState.devices);
  }


devices$ =this.appStateManager.getFromStore<ServiceProvider>(state => 
    state.serviceProviderState.selectedServiceProvider)
    .subscribe(data=>{
    this.deviceService.getAllDevices(data.id)
    .subscribe((devices: Array<Device>) => {
      console.log(devices);
      this.appStateManager.saveToStore(new SetAllDevices(devices));
    });
    });

在上面的代码中,我从appStateManager获取数据,这只是商店api的包装器。在获得selectedId之后,我调用了getAllDevices,它为我提供了一个过滤的数据集。我可以在console.log中看到我想要的数据集。

现在我需要在我的网格中显示这些设备$。我为此编写了如下代码:

      @Component({
         selector: 'device-list',
         template: '<data-grid [devices]="devices"></data-grid>',
          })

     export class DeviceListContainer implements OnInit {
  devices: Device[];  
  devices$= this.monitoring.devices$;     
  constructor(private monitoring: MonitoringSandbox) {       
    this.monitoring.getAllDevices().subscribe((data)=>{          
       this.devices=data;
       console.log(this.devices);
     })       
  }

我的网格没有被填满。我哪里出错?

2 个答案:

答案 0 :(得分:1)

您的DeviceListContainer中的

devices $是一个订阅,您已经在sandox中订阅了它,它不是一个Observable&lt;数组&lt;元件&gt;取代。您还需要在设备内再次订阅$您需要使用rxjs运算符来格式化您的请求。对于建筑尝试使用它如此

 let deviceSubscribtion = this.monitoring.getAllDevices().take(1).subscribe(data=> {
         this.devices=data;
         console.log(this.devices);
  });

在销毁组件时不要忘记取消订阅deviceSubscribtion,否则最终会导致内存泄漏

答案 1 :(得分:0)

对于代码的第一部分,您正在执行的订阅位于另一个订阅中。 Angular使用rxjs可以帮助您很多。您应该与一些运营商组成该订阅。

例如

someObserble$.pipe(
  mergeMap(someObserbleResulat => {
   // return some Obserble
  }),
  switchMap(someObserbleResulat => {
   // return some Obserble
  })
)

在编写SwitchMap时,您正在完成上一个可观察的对象。 撰写MergeMap时,您没有完成先前的可观察性

使用switchMap,我们可以将您的代码清除为==>

this.appStateManager.getFromStore<ServiceProvider>
.pipe(
    switchMap(state => state.serviceProviderState.selectedServiceProvider),
    switchMap(data => this.deviceService.getAllDevices(data.id)),
   ) 
  .subscribe((devices: Array<Device>) => {
     console.log(devices);
     this.appStateManager.saveToStore(new SetAllDevices(devices));
  });

您可以看到此代码如何变成更清洁,可读和可维护的代码。

您应该使用有角

aync
管道,该管道会在ngOnDestory调用时自动订阅您的可观察对象并取消订阅。

@Component({
       selector: 'device-list',
       template: '<data-grid [devices]="devices$ | async"></data-grid>',
})
export class DeviceListContainer implements OnInit {
   devices$: Obserble<Device[]>;  

   constructor(private monitoring: MonitoringSandbox) {       
     this.devices$ = this.monitoring.getAllDevices() 
}

如果要添加控制台以查看此订阅中返回的内容,可以添加 点击运算符

.pipe (
   tap( res => { console.log(res)})
)

一些有用的读物​​:

https://netbasal.com/rxjs-six-operators-that-you-must-know-5ed3b6e238a0 https://www.nerdeez.com/articles/rxjs/top-operators

享受