如何在不重新加载页面的情况下跟踪树 DOM 更改?角

How to track tree DOM changes without reloading the page? Angular

提问人:Alexandr Boroshenko 提问时间:10/7/2023 更新时间:10/8/2023 访问量:41

问:

我需要你的帮助。我有一小段代码,我正在尝试实现以下逻辑 - 我有一个菜单列表。如果我有这个角色,请不要删除任何内容,但如果非root角色已更改,则删除菜单项。现在我的逻辑有效,但只有在重新加载页面之后。具有 root 角色,更改为另一个角色,并且只有在重新加载页面后才会删除该元素。,不幸的是没有帮助我。请告诉我如何在不重新启动的情况下跟踪它或删除和添加其结果?谢谢rootChangeDetectorRefMutationObserverapplicationRef.tick()

@ViewChildren('menuItems') menuElements: QueryList<ElementRef>;

ngAfterViewInit() {
    let menuArrayElements = this.menuElements.toArray();
    let element = menuArrayElements.find((el) => el.nativeElement.innerText === 'Platform setup');
    if (this.role !== 'root') {
        element.nativeElement.parentNode.removeChild(element.nativeElement);
    }

    const observer = new MutationObserver(list => {
        console.log(list)
    })
    observer.observe(element.nativeElement, { childList: true, subtree: true });
}
Angular DOM 突变观察者

评论

0赞 Misha Mashina 10/7/2023
角色是如何变化的 - 通过应用程序内部的操作,还是通过 api/后端的操作?换句话说,你如何获得用户的角色?
0赞 Alexandr Boroshenko 10/7/2023
@MishaMashina 使用 API 更改角色。有几个角色可供选择,菜单应该改变。 - 使用 Ngrx 和 API,我关注并更改角色this.store$.select(selectors.currentUserRole) .subscribe(role => )
0赞 Misha Mashina 10/7/2023
我猜我不清楚。我想知道的是,您是通过 UI 更改角色,还是在 api 中手动(或通过某些服务)更改角色。如果你通过UI改变它,那么你可以把它变成一个订阅的主题,但是如果你在api中改变它,你将无法通过简单的http订阅在前端触发改变 - 你需要一个套接字或其他东西实时监听。
0赞 Alexandr Boroshenko 10/7/2023
@MishaMashina每个角色都有几个按钮。通过UI,我更改了用户角色。让我们在聊天中继续这个话题,因为现在可能会有一个警告,不要在评论中讨论这个话题

答:

0赞 alexdefender93 10/8/2023 #1

我建议使用 Angular 工具,除了调用 DOM API。我的意思是你不应该直接在 Angular 应用程序中使用。相反,我建议使用绑定。例如,您可以在 component 中编写:removeChild

private role$ = new BehaviorSubject('root');  // should be updated when the role changes

private menuItems$ = [{
   name: 'first link',
   href: '/first',
   rootOnly: false
}, {
   name: 'second link',
   href: '/second',
   rootOnly: true
}];

// an observable that removes menu item when the role changes
menuItemsProtected$ = combineLatest([this.role$, this.menuItems$]).pipe(
  map(([role, items]) => {
    if (role === 'root') {
      return items;
    }
    return items.filter((e) => !e.rootOnly);
  })
);

然后在您的模板中:

<ul *ngFor="let item of menuItemsProtected$ | async">
  <li>
    <a [routerLink]="item.href">
      {{item.name}}
    </a>
  </li>
</ul>

现在,您只需要作为 BehaviorSubject 实现(例如),请参阅此处的更多详细信息 https://www.learnrxjs.io/learn-rxjs/subjects/behaviorsubjectrole$