Управление подпиской на наблюдаемое в одном компоненте влияет на подписку в другом компоненте. - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть служба меню, которая предоставляет наблюдаемые моим компонентам. У меня есть два компонента, которые должны использовать эти данные. Компонент Side Menu (с вложенными дочерними элементами) и редактор меню (который просто хочет получить плоский список всех элементов меню без дочерних элементов). Весь мой код работал нормально, пока я не попытался сгладить структуру меню для редактора. При открытии редактора меню боковое меню теряет все вложенные родительско-дочерние отношения.

Я подтвердил, что моя функция выравнивания вызывает ее, если я ее удалю, то этого не произойдет. Если я go перехожу на другую страницу, этого не произойдет.

Как я могу настроить это так, чтобы, если я манипулирую данными из наблюдаемого (по сути, создавая новые объекты) в одном компоненте, который он не использует? не влияет на другие компоненты.

menu.service.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() {
  }
}

menu-manager.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;
    }
  }

}

Behaviour in Angular

...