从DOM元素

时间:2015-11-19 13:08:00

标签: angular interact.js

已经回答了如何从Angular 2组件中获取DOM元素:ComponentRef.location.nativeElement(ComponentRef.location给出了可以直接访问DOM的ElementRef)。

如何做相反的事情,即当我只有原生DOM对象时获取对ComponentRef的引用?

当我尝试使用interact.js拖放Angular 2组件时就是这种情况。该库使用回调函数来通知拖动哪个元素,以及我们尝试删除哪个元素。提供了一个event对象,我找到的唯一有用信息是DOM元素(target属性)。

示例:

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

您可以在src/Interactjs.ts中查看处理程序。打开控制台以查看关联的日志并将组件拖放到另一个组件上。我有DOM的元素信息,但我想要Angular组件,比如说访问count属性。

结果和尝试:

我找到了一个solution for the jquery-ui-draggable plugin,但这个技巧在这里不起作用,至少对于要放弃的目标而言。

还有topics关于如何在DOM中插入,谈论DomAdapter,但我没有找到任何似乎有助于从DOM到Angular组件引用的方法。

我只是考虑对我的组件进行手动搜索:在DOM节点中循环,计数以找到位置,并从同一位置的组件列表到达组件,但它太丑了......

欢迎提出任何建议。谢谢你的阅读!

2 个答案:

答案 0 :(得分:3)

这可以使用ElementProbe API来实现。它主要用于调试/量角器集成,类似于Angular 1中的element.scope()

要使用此API,您需要在ELEMENT_PROBE_PROVIDERS来电中加入bootstrap()。然后,您可以通过调用全局ng.probe()来获取任何组件实例。

例如,以下是获取当前事件目标的组件实例的方法:

ng.probe(event.target).componentInstance

<强> Updated Plunker showing this is action

您可以看到ElementProbe API Here的实际实现。

答案 1 :(得分:0)

我必须这样做。我能够通过在&#34; parent&#34;中使用@ViewChildren的组合来实现它。组件类并在&#34; child&#34;上设置唯一标识符。组件本身。

所以,它是父组件,你有:

@ViewChildren(YourChildComponent)
elements: QueryList<YourChildComponent>;

然后,在您的子组件中,执行以下操作(请注意我导入了angular2 uuid包,但您可以使用任何机制生成唯一ID):

constructor(private elementRef:ElementRef) {    
    this.UniqueID = UUID.UUID();
    this.elementRef.nativeElement.setAttribute('unique-id', this.UniqueID);
}

 //and we define a public property here
UniqueID: string;

现在,您可以通过以下标识符访问您的孩子并进行匹配:

private findElementByNativeDOMObject(el: any) : YourChildComponent{


let uniqueId = el.attributes.getNamedItem('unique-id').value;
if ( ! uniqueId)
  return null;

// ok, let's go through our children
return this.elements.find( x=> x.UniqueID == uniqueId);

}