【问题标题】:Get ComponentRef from DOM element从 DOM 元素中获取 ComponentRef
【发布时间】:2016-02-21 15:37:41
【问题描述】:

已经回答了如何从 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节点中循环,计数找到位置,并从组件列表中到达相同位置的组件,但它是如此丑陋......

欢迎对此提出任何建议。感谢阅读!

【问题讨论】:

    标签: angular interact.js


    【解决方案1】:

    我只需要这样做。我能够通过在“父”组件类中使用@ViewChildren 的组合并在“子”组件本身上设置唯一标识符来完成它。

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

    @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);
    

    }

    【讨论】:

      【解决方案2】:

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

      要使用此 API,您需要在您的 bootstrap() 调用中包含 ELEMENT_PROBE_PROVIDERS。然后,您将能够通过调用全局 ng.probe() 来获取任何组件实例。

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

      ng.probe(event.target).componentInstance
      

      Updated Plunker showing this is action

      你可以看到ElementProbe APIHere的实际实现。

      【讨论】:

      • 太棒了!我以为不可能,谢谢!我从 angular gitter group 得到的建议是改变设计以使其更像 Angular 方式。实际上,我已经迁移到完全不同的代码结构以避免操纵 DOM,但是您的解决方案清楚地解决了我的问题中提出的问题。
      • 2.0下这个还存在吗?
      猜你喜欢
      • 2022-12-05
      • 2014-11-24
      • 2022-01-17
      • 2012-12-10
      • 2018-12-17
      • 2016-02-21
      • 1970-01-01
      • 2018-11-29
      • 2011-04-06
      相关资源
      最近更新 更多