从子组件获取父组件的elementRef

时间:2018-02-15 21:19:17

标签: angular typescript angular5

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

我的孩子组件有一个特定的要求:

  
      
  1. 点击 child 时,会切换其详细信息的显示
  2.   
  3. 孩子放在ParentComponent内时,当点击时, child 应该与1中的相同
  4.   

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

所以唯一应该处理的地方是ChildComponent。通过以下方式轻松前往ParentComponent

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

但是这没有用,因为我需要父组件的ElementRef,这样我就可以将click事件处理程序附加到它。

我如何以Angular的方式获得它?

  

我知道我可以获得ChildComponent的{​​{1}}并向上遍历DOM寻找最近的{{1}这个元素,但这可能比正确的Angular方法更糟糕。我很确定必须有更好的方法。

2 个答案:

答案 0 :(得分:1)

我想到了ATM 2的想法:

1)将父组件作为可选参数注入子组:

对于这种情况,父级应该通过公共成员公开elementRef实例。

<强>赞成

  • 易于实施

<强>反政府

  • 孩子与父母的紧密联系:如果现在你有N型父母怎么办?您会在子构造函数中定义N-Optional属性吗?为所有父母使用基类?在这种情况下,您必须在所有N-Parent组件的组件级别使用显式提供程序。

2)跨父母和子女共享服务实例以跟踪点击事件

在这种情况下,父和子共享服务的公共实例,或多或少看起来像这样:

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

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

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

基本上,父母和孩子都可以通过click方法发出新事件。他们还可以使用公共clicks$流订阅该流,并在事件上运行逻辑。

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

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

层次结构依赖注入器将负责提供FooParent中包含的子组件以及父组件中的ClickTracker实例。

<强>优点:

  • 儿童与父母之间没有紧密联系

<强>反政府

  • 家长现在负责创建新服务。

答案 1 :(得分:-2)

您可以使用输入绑定。

例如在parent.component.ts中

public parentRef: ElementRef;

constructor(elementRef:ElementRef) {
  this.parentRef = elementRef;
}

在child.component.ts中声明一个输入绑定

@Input public parentRef: ElementRef;

然后在您的parent.component.html传递对子组件的引用

<child-component [parentRef]="parentRef"></child-component>