typescript 获取根组件 ElementRef 或 ComponentRef angular 2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34970778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:14:12  来源:igfitidea点击:

Get root component ElementRef or ComponentRef angular 2

typescriptangular

提问by Kliment

I'm building modal service in angular 2. I resolve most of the issues but i have problem placing the modal component in the body element in a nice angular way. I use DynamicComponentLoader.loadNextToLocationfunction to get the modal component and place it next to the ElementRefthat is uset in DynamicComponentLoader.loadNextToLocationfunction. But when i don't want to place the created modal inside some component i have to manipulate DOM to insert the created modal. My question is can i use the root element in my application in the modal service? I want to achieve this when specific element isn't provided as container for the modal.

我正在 angular 2 中构建模态服务。我解决了大部分问题,但是我在以一种很好的角度方式将模态组件放置在 body 元素中时遇到了问题。我使用DynamicComponentLoader.loadNextToLocation函数来获取模态组件并将它ElementRef放在DynamicComponentLoader.loadNextToLocation函数中使用的旁边。但是当我不想将创建的模态放在某个组件中时,我必须操纵 DOM 来插入创建的模态。我的问题是我可以在模态服务的应用程序中使用根元素吗?当特定元素未作为模式的容器提供时,我想实现这一点。

var elementRef = DOM.query('app');
this.componentLoader.loadNextToLocation(ModalBackdrop, elementRef, backdropBindings)

回答by pixelbits

To get a reference to the root component, you can inject ApplicationRef:

要获得对根组件的引用,您可以注入ApplicationRef

constructor(private app:ApplicationRef)
{
      let element: ElementRef = this._app['_rootComponents'][0].location;
}

回答by Günter Z?chbauer

appElementRef: ElementRef;
constructor(private applicationRef:ApplicationRef, injector: Injector) {
  this.appElementRef = injector.get(applicationRef.componentTypes[0]).elementRef;
}

The AppComponentwould need to provide the elementReffield that returns the ElementRefthough.

TheAppComponent将需要提供elementRef返回ElementRef尽管的字段。

See also https://github.com/angular/angular/issues/6446

另见https://github.com/angular/angular/issues/6446

回答by Victor K

The problem is that to get the root ElementRef, your application should be bootstrapped. And in some situations (getting ElementRef in services) we should wait for that. My solution:

问题是要获取根 ElementRef,您的应用程序应该被引导。在某些情况下(在服务中获取 ElementRef)我们应该等待。我的解决方案:

import {Injectable, ApplicationRef, ElementRef} from 'angular2/core';

@Injectable()
export class SomeService {
  private _appElementRef: ElementRef;

  constructor(appRef: ApplicationRef) {
    appRef.registerBootstrapListener(appComponentRef => {
      this._appElementRef = appComponentRef.location;
    });
  }
}

回答by Fredrik_Macrobond

This works in Angular 5.2.9

这适用于 Angular 5.2.9

Add a public ElementRef in your root component's constructor:

在根组件的构造函数中添加一个公共 ElementRef:

export class AppComponent { 

constructor (public eltRef: ElementRef) { }

And in the component where you want to access the root, do this:

在要访问根的组件中,执行以下操作:

private rootRef: ElementRef;
constructor(private appRef: ApplicationRef) {
    this.rootRef = (this.appRef.components[0].instance as AppComponent).eltRef;
}

回答by BeetleJuice

The available answers didn't work for me:

可用的答案对我不起作用:

  • The selected answer requires the root component to have injected ElementRef.
  • The highest-voted answer relies on accessing private variables, so it could break without warning (only public API changes are considered breaking changes and are documented)
  • Other answers assume that the root component is of type AppComponent.
  • 所选答案要求根组件已注入ElementRef
  • 最高投票的答案依赖于访问私有变量,因此它可能会在没有警告的情况下中断(只有公共 API 更改才被视为中断更改并记录在案)
  • 其他答案假定根组件的类型为AppComponent

In my situation, I am developing a 3rd party library so I cannot make any assumption that the root is called AppComponentor that it has ElementRefinjected. This is what worked for me (Angular 6.1)

在我的情况下,我正在开发一个 3rd 方库,所以我不能假设根被称为AppComponent或者它注入了ElementRef。这对我有用(Angular 6.1)

private readonly rootRef: ElementRef;

constructor(private appRef: ApplicationRef) {
  this.rootRef = appRef.components[0].injector.get(ElementRef);
}

I later discovered that if I tried to inject and use the service very early after Angular bootstraps, an exception was thrown because appRef.componentsis still empty. So I instead modified the code to make rootRefa promise that resolves with ElementRef. This way the consuming code can call it immediately without raising an exception but will have to wait for the ElementRefto resolve:

后来我发现,如果我在 Angular 引导后很早就尝试注入和使用该服务,则会抛出异常,因为appRef.components它仍然为空。因此,我改为修改代码以做出rootRefElementRef. 这样,消费代码可以立即调用它而不会引发异常,但必须等待ElementRef解决:

private readonly rootRef: Promise<ElementRef>;

constructor(appRef: ApplicationRef) {
  this.rootRef = new Promise(resolve => {
    setTimeout(
      () => resolve(appRef.components[0].injector.get(ElementRef)),
      100
    );
  });
}