-->

Angular2 dom.query to ElementRef

2019-08-08 22:47发布

问题:

Is it possible to convert the DOM.query to ElementRef.

I have an application, with ... and have a service to the backend, the service doesnt have does not have ElementRef on its constructor and might be layers deep within the app. I was thinking that i could query the dom and reuse the loadIntoLocation feature this.componentLoader.loadIntoLocation(Notification, Dom.query('app'),'notification',...)

Is there a way to get the reference to the app component or the root component? Or is there a way to query the dom and convert it to ElementRef?

I want to use loadIntoLocation instead of pure dom because i think its better for testing.

回答1:

If your root component is called AppComponent, I believe you could inject it using @Host() appComponent : AppComponent in the constructor of your other component. And then you can access appComponent.location to get its ElementRef. And then you can pass this one to your service. What this will do basically, it will ask to inject the host of type AppComponent, and if the current Injector is not able to find it, it tries with the parentInjector until it can resolve the dependency. In any way you somehow need to pass an ElementRef to your service I think. You can look at the code of angular2_material for inspiration : dialog source.

The downside of the solution above is that you need to know the type of AppComponent, so the user of your service ( the component you define ), will hardwire the type of your root component. That's why I'd rather do it simply with the current ElementRef of your current component, and then you can move it some place else with DomAdapter. The ElementRef is as far as I understood the reference of your component to the DOM, so you can create your component wherever you are, load it next to your current component's location and then just move it in the DOM, and this could even be the body of your page, which should be available anywhere. The way they seem to do this in the dialog of angular2_material is by using the appendChild method of DomAdapter. And you can simply get DOM from importing it from DomAdapter : import {DOM} from 'angular2/src/dom/dom_adapter';. This will give you an instance of DomAdapter to work with.

Also it seems that in the future we'll have an improved API to directly load a component into a specific place in the DOM, so you won't need any ElementRef anymore and you could just define an id somewhere and load it there, or use the body element directly without having to load it, and then append it to a specific place.