【问题标题】:Angular component siblings calling a function in service and watching it not workingAngular 组件兄弟姐妹在服务中调用函数并观察它不起作用
【发布时间】:2020-03-28 05:46:35
【问题描述】:

我有两个组件和一个服务。

在组件 1 中,我有一个在初始化时立即调用的函数。

组件 1:

  ngOnInit() {
    this.getItems();
  }

  getItems(){
    this.mainService.getItems().subscribe(items => { //WATCH SERVICE
      this.items = items;
    });
  }

现在,在服务中,我拥有正确完成工作的函数 getItems():

主要服务:

public itemCategoryId = new BehaviorSubject<any>(1); //watch category  

getItems(): Observable<Item[]> { //THE MAIN FUNCTION
    return this.http.get<Item[]>(Constants.endPoint + Constants.allPins + this.itemCategoryId.value + '/1');
}

changeCategoryId(id) {
    this.itemCategoryId.next(id);
}

现在,在组件 2 中,我通过一个新号码激活服务中的功能 changeCategoryId这会改变 itemCategoryId BehaviorSubject。

组件 2

  changeCategory(id) {
    console.log("ADMIN Category is now: ", id);
    this.mainService.changeCategoryId(id);
  }

所以现在,在组件2中点击后,服务中的函数getItems()有不同的http get请求。这个新请求应该在组件 1 中加载。但它没有。

我的问题是,为什么组件 1 没有从服务中的 getItems() 函数获取新项目,即使我订阅了它?

我应该再调用一次组件 1 中的 getItems() 函数还是我缺少其他解决方案?

【问题讨论】:

    标签: angular


    【解决方案1】:

    您的 getItems 函数返回一个值并完成,这意味着订阅结束。

    你应该将它与你的 BehaviorSubject 结合起来:

    function getItems(): Observable<Item[]> {
        return this.itemCategoryId.pipe(
            switchMap(id => this.http.get<Item[]>(Constants.endPoint + Constants.allPins + id + '/1'))
        )
    }
    

    https://www.learnrxjs.io/operators/transformation/switchmap.html

    【讨论】:

      【解决方案2】:

      如果您想在 BehaviorSubject 发生变化时触发事件(下一步),您还应该订阅它

      您没有订阅该主题,因此您要运行的方法不知道它的状态变化。

      PS:还记得取消订阅(this.itemCategoryId.unsubscribe())该主题,例如在 ngOnDestroy 方法中,以防止内存泄漏。

      【讨论】:

        【解决方案3】:

        由于你的服务中的 getItems() 函数是一个 HTTP 调用,Angular 将在完成后自动取消订阅这个函数(所以它不会再监听这个)。 由于只在组件 1 的 ngOnInit 函数中调用,所以只会在组件 1 初始化时执行。

        如果您希望组件 1 在您单击组件 2 中的按钮时调用 getitems() 函数,您应该考虑这样的事情:

        组件 1:

        private unsubscribe = new Subject();
        
         ngOnInit() {
            this.subscription = this.mainService.itemCategoryId.asObservable().pipe(takeUntil(this.unsubscribe)).subscribe(id => this.getItems(id));
          }
        
          getItems(id: number){
            this.mainService.getItems(id).subscribe(items => {
              this.items = items;
            });
          }
        
          ngOnDestroy() {
             this.unsubscribe.next();
             this.unsubscribe.complete();
          }
        

        当组件被销毁(或其他地方,取决于您的用例)时,不要忘记取消订阅行为主题

        服务:

        public itemCategoryId = new BehaviorSubject<any>(1); //watch category  
        
        getItems(id: number): Observable<Item[]> { //THE MAIN FUNCTION
            return this.http.get<Item[]>(Constants.endPoint + Constants.allPins + id + '/1');
        }
        
        changeCategoryId(id) {
            this.itemCategoryId.next(id);
        }
        

        【讨论】:

          猜你喜欢
          • 2014-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-23
          • 2019-05-06
          • 2018-04-12
          • 2022-08-19
          相关资源
          最近更新 更多