【问题标题】:unable to render data from ngrx store to component无法将 ngrx 存储中的数据渲染到组件
【发布时间】:2019-05-01 22:13:04
【问题描述】:

我正在使用 ngrx 和 angular。 我有一个组件,它在模块“A”中有一个下拉菜单。在更改下拉列表时,我在我的 ngrx 商店中设置了选定的值。

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

我能够在我的沙盒中获取数据集。这个 Sandox 只不过是一个层 b/w 组件和存储

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 获取数据,这不过是 store 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);
     })       
  }

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

【问题讨论】:

    标签: angular ngrx


    【解决方案1】:
    您的 DeviceListContainer 中的

    devices$ 是订阅,您已经在 Sandox 中订阅了它,它不是 Observable>。您还需要在 devices$ 中再次订阅,您需要使用 rxjs 运算符来格式化您的请求。对于施工尝试像这样使用它

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

    销毁组件时不要忘记取消订阅设备订阅,否则会导致内存泄漏

    【讨论】:

      【解决方案2】:

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

      例如

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

      当你编写 SwitchMap 时,你正在完成之前的 observable。 当你编写 MergeMap 时,你没有完成之前的 observable

      使用 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 调用时自动订阅您的 observable 并取消订阅。
      @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

      享受

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        • 2018-06-30
        • 2012-06-29
        • 2017-03-08
        相关资源
        最近更新 更多