It has already been answered how to get the DOM element from an Angular 2 component: ComponentRef.location.nativeElement
(ComponentRef.location gives the ElementRef that gives a direct access to DOM).
But how to do the opposite, i.e. get the reference to the ComponentRef when I only have the native DOM object?
I am in the case when I try to drag/drop Angular 2 components using interact.js. The library uses callback functions to notify which element is dragged, and on which element we are trying to drop. An event
object is provided, and the only useful information I found was the DOM element (target
attribute).
Example:
interact('my-component-tag').draggable({
// ...
onstart: function (event:any) {
var dom = event.target; // ref to the <my-component-tag> tag
// How to find the Angular ComponentRef object here?
}
// ...
}).dropzone({
// ...
ondragenter: function (event:any) {
var targetDom = event.relatedTarget; // targeted <my-component-tag> tag
// Same question here,
// to identify where we want to insert the dragged element.
}
// ...
});
Plunker here
You can check the handlers in src/Interactjs.ts
. Open the console to see associated logs and drop a component on another. I have information about elements by the DOM, but I want Angular components instead, let's say access the count
attribute.
Findings and tries:
I found a solution for the jquery-ui-draggable plugin, but this trick does not work here, at least for the target where to drop.
There are also topics about how to insert in the DOM, talking about the DomAdapter, but I haven't found any method that seems to help from DOM to Angular component reference.
I just thought about a manual search over my components: looping in the DOM nodes, count to find the position, and reach the component from the component list at the same position, but it is so ugly...
Any advice on that is welcome. Thanks for reading!
This could be achieved using the ElementProbe API. It is mainly intended for debugging / protractor integration, similar to element.scope()
in Angular 1.
In order to use this API, you would need to include ELEMENT_PROBE_PROVIDERS
in your bootstrap()
call. You will then be able to get any component instance by calling the global ng.probe()
.
For example, here is how you get the component instance for the current event target:
ng.probe(event.target).componentInstance
Updated Plunker showing this is action
You can see the actual implementation of the ElementProbe API Here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With