利用BehaviorSubject从后端拉出的第一个值 - 默认值

时间:2017-11-28 15:39:01

标签: angular rxjs angular2-services angular2-observables

我有3个主要BehaviorSubjectuserorganizationsselectedOrganization

首先需要从后端获取用户,然后获取他的组织,然后选择第一个组织(这就是我使用flatMap的原因)。所有这些都在user.service.ts

user = new BehaviorSubject<Object>({});

constructor(private http: Http, public settings: SettingsService, public organizationService: OrganizationService) {
  this.setUserData();
}

  setUserData() {

  return this.organizationService.getAssignedOrganizations()
  .flatMap(
    (organizationResponse) => {
      this.organizationDataInfo = organizationResponse;
      return this.getUserInformation();
    }
  )
  .subscribe(
    data => {
      this.user.next(data);
      this.organizationService.organizations.next(this.organizationDataInfo);
      this.organizationService.selectedOrganization.next(this.organizationDataInfo[0]); //<------ here we set the selectedOrganization, our main thing.
    }
  );

}

我们在BehaviorSubject中声明了另外两个organizations.service.ts

  organizations = new BehaviorSubject<any>([]);
  selectedOrganization = new BehaviorSubject<Object>({});

现在,我想通过使用他的id在后端进行其他api调用来在组件中使用此selectedOrganization

ngOnInit() {
     this.organizationService.selectedOrganization.subscribe((val) => {

          this.selectedOrganization = val;
          this.orderService.getOrders("apicall/"+this.selectedOrganization.id)
          .subscribe(res=> console.log(res))
      });
}

selectedOrganization没有初始值,因为它将从user.service.ts构造函数中获取数据(这是我做错的地方)。如果我将添加1秒的超时,它将收到主题的值。

如何在没有计时的情况下解决这个问题?

这可以使用APP_INITIALIZER来解决,因此我可以在加载应用之前致电setUserData(),然后再使用此方法我需要登录我的应用程序=无法正常工作。

1 个答案:

答案 0 :(得分:0)

您的代码中有一个错误,即:

this.selectedOrganization = val;

selectedOrganization是一个BehaviorSubject观察者,你不能像这样使用它。因此,请使用val.id

调用所选组织的ID

问题的一个解决方案可能是,只检查一个空值,如果它是空的,则跳过该呼叫。所以你的代码就像:

ngOnInit() {
  this.organizationService.selectedOrganization.subscribe((val) => {
    if(val !== ' '){
      this.orderService.getOrders("apicall/"+val.id)
        .subscribe(res=> console.log(res))
    }
  });
}

我认为另一种解决方案更适合您的情况是设置一个布尔标志。所以在你的user.service.ts:

public isDataSet: Boolean = false;  //1
setUserData() {
  return this.organizationService.getAssignedOrganizations()
    .flatMap(
      (organizationResponse) => {
        this.organizationDataInfo = organizationResponse;
        return this.getUserInformation();
      }
    )
    .subscribe(
      data => {
        this.user.next(data);
        this.organizationService.organizations.next(this.organizationDataInfo);
        this.organizationService.selectedOrganization.next(this.organizationDataInfo[0]);
        this.isDataSet = true;  //2
      }
    );
  }

所以在(1)中声明一个布尔变量 isDataSet 并将初始值设置为false。在(2) getAssignedOrganizations 中,只要获得数据,就会将其设置为true。因此,在(3)您的组件中,您可以检查 isDataSet ,只有在获得数据时才会出现这种情况,并且您的组件将是:

ngOnInit() {
  this.organizationService.selectedOrganization.subscribe((val) => {
    if(this.userService.isDataSet){ . //3
      this.orderService.getOrders("apicall/"+val.id)
        .subscribe(res=> console.log(res))
      this.userService.isDataSet = false;  //4
    }
  });
}

希望这个能帮到你。