从子组件获取父组件的 elementRef

Get parent component's elementRef from child component

我有 ParentComponentChildComponent。父组件使用 ng-content 因此它可以在任何类型的 DOM 元素层次结构中包含任何内容。

我的子组件有特定要求:

  1. When child is clicked it toggles the display of its details
  2. When child is placed inside ParentComponent, then when the parent is clicked, child should do the same as in 1.

由于父级可以有任何内容,因此将 @ContentChild 添加到父级似乎是不合理的,因为......很好的封装。

所以唯一应该处理的地方是 ChildComponent。通过以下方式到达 ParentComponent 非常简单:

// ChildComponent ctor
constructor(@Optional() parent: ParentComponent) { ... }

但这无济于事,因为我需要父组件的 ElementRef,这样我才能将点击事件处理程序附加到它。

如何通过Angular方式获得?

I know I could get ChildComponent's ElementRef and traverse the DOM upwards looking for the closest ParentComponent's element, but that's likely more of a hack than the proper Angular way of doing this. I'm pretty sure there must be some better way.

我想到了 ATM 2 的想法:

1)将parent组件作为可选参数注入到child中:

对于这种情况,parent 应该通过 public 成员公开 elementRef 实例。

优点

  • 易于实施

对比:

  • child 与 parent 的紧密耦合:如果现在您拥有 parent 的 N-types 会怎么样?您会在 child 构造函数中定义 N-Optional 属性吗?对所有 parent 都使用基数 class?在这种情况下,您将必须在所有 N-Parent 组件上在组件级别使用显式提供程序。

2) 在 parent 和 child 之间共享一个服务实例以跟踪点击事件

在这种情况下,parent 和 child 共享一个公共服务实例,该实例大致如下所示:

export class ClickTracker {
   private readonly _clicks$ = new Subject<void>();
   readonly clicks$ = this._clicks$.asObservable();

   ngOnDestroy(){
      this._click$.complete();
   }

   click(){
      this._clicks$.next(); 
   }
}

基本上,parent和child都可以通过click方法发出新的事件。他们还可以通过使用 public clicks$ 流和事件上的 运行 逻辑来订阅该流。

要在 DOM 层次结构中共享实例,必须在 parent 组件级别提供 ClickTracker class 的新实例:

@Component({
  providers: [ClickTracker]
})
export class FooParent{}

分层依赖注入器将负责提供 FooParent 中包含的 child 组件以及来自 parent.

ClickTracker 实例

优点:

  • child 和 parent(s)
  • 之间没有紧密耦合

对比:

  • Parents 现在负责创建新服务。