首页 > 解决方案 > 在一个组件中操作对 observable 的订阅会影响另一个组件中的订阅

问题描述

我有一个菜单服务,它为我的组件提供 observables。我有两个组件需要使用这些数据。一个 Side Menu 组件(带有嵌套的子元素)和一个菜单编辑器(只需要一个没有子元素的所有菜单元素的平面列表)。我所有的代码都运行良好,直到我尝试为编辑器展平菜单结构。打开菜单编辑器后,侧边菜单会丢失所有嵌套的父子关系。

我已经确认是我的扁平化功能导致了它,如果我删除它,那么它就不会发生。如果我转到另一个页面,它不会发生。

我如何设置它,以便如果我在一个组件中操作来自 observable 的数据(通过本质上创建新对象),它不会影响其他组件。

菜单服务.ts

export class MenuService {
  private _loading$ = new BehaviorSubject<boolean>(true);
  private _nestedMenu$ = new BehaviorSubject<MenuItem[]>([]);
  private _get$ = new Subject<void>();

  constructor(private http: HttpClient) {
    this.getAllMenuItems();
  }


  getAllMenuItems() {
    return this.http.get<MenuItem[]>(`${environment.privateApiUrl}/System/GetAllMenuItemList`)
      .subscribe({
        next: (result => {
          this._nestedMenu$.next(result);
        }),
        error: ( catchError(<T>(error: any, result?: T) => {
          console.log(error);
          return of(result as T);
        }))
      });
  }

  get nestedMenu$() { return this._nestedMenu$.asObservable(); }
  get loading$() {return this._loading$.asObservable(); }


}

side-menu.component.ts

export class SideMenuComponent implements OnInit {
  loading = false;
  menuItems: MenuItem[];

  constructor(public sideNavService: SideNavService, private http: HttpClient, private menuService: MenuService) {
    this.menuService.nestedMenu$.subscribe({
      next: ((value) => {
        this.loading = true;
        const menuArray: MenuItem[] = [];
        for (const node of value) {
          if (node.parent == null) {
            menuArray.push(node);
          }
        }
        this.menuItems = menuArray;
        this.loading = false;
      }),
      complete: (() => {
      })
    });
  }

  ngOnInit() {
  }
}

菜单管理器.component.ts

export class MenuManagerComponent implements OnInit {
  collapsed = false;
  faPen = faPen;
  fullMenuList: MenuItem[];
  menuItems: [{depth: number, menuItem: MenuItem}?] = [];
  constructor(private menuService: MenuService) { }

  ngOnInit() {
    this.menuService.nestedMenu$.subscribe({
      next: ((value) => {
        this.fullMenuList = value;
        this.flattenMenu(this.fullMenuList.filter(x => x.parent === null),0);
      })
    });
  }

  flattenMenu(menuItems: MenuItem[], depth: number) {
    for (const menuItem of menuItems) {
      this.menuItems.push({depth, menuItem});
      this.flattenMenu(menuItem.children, depth + 1);
      menuItem.children = null;
    }
  }

}

Angular 中的行为

标签: angularangular2-observables

解决方案


推荐阅读