【问题标题】:How to add a component into a elementref?如何将组件添加到元素引用中?
【发布时间】:2020-01-02 10:53:18
【问题描述】:

我想将一个组件作为子元素添加到 elementref 中并可以访问它的属性。

const element: HTMLElement = document.createElement('div');

element.innerHTML = // Component needs to be added here

// Need to have access to properties of the Component here

我在我的项目中添加了一个完整的日历,我需要为时间线添加自定义资源元素。为此,我只能访问 HTMLElement 和一些数据。所以我想要做的是将一个初始化的组件传递给 HTMLElement。

现在我唯一的选择是将 html 作为字符串写入并将其传递给 innerHTML。有更好的选择吗?

【问题讨论】:

标签: angular


【解决方案1】:

在我的一个项目中,我通过这种方式实现了与您的要求类似的东西。让我知道是否有帮助?

constructor(private componentFactoryResolver: ComponentFactoryResolver,
            private injector: Injector, 
            private appRef: ApplicationRef) {
  const componentFactory = this.componentFactoryResolver.resolveComponentFactory(DynamicComponent); // Your dynamic component will replace DynamicComponent

  const componentRef = componentFactory.create(this.injector);

  this.appRef.attachView(componentRef.hostView);  

  const domElem = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;

  const element: HTMLElement = document.createElement('div');
  element.appendChild(domElem); // Component needs to be added here
  document.body.appendChild(element);
}

这样您就可以将动态组件引用为componentRef

【讨论】:

  • 感谢您的回答。我可以使用 componentRef 访问实例。对吗?
  • @SachithRukshan 是的
  • 要获取domElem,我们可以使用componentRef.location.nativeElement;
【解决方案2】:

您也许可以使用Renderer2

export class AppComponent { 
@ViewChild('addButton') 
  private animateThis: ElementRef;  
  constructor(private renderer: Renderer2) {}

  addBtn() {
    const button = this.renderer.createElement('button'); 
    const buttonText = this.renderer.createText('This is a button');
    this.renderer.appendChild(button, buttonText);
    this.renderer.appendChild(this.animateThis.nativeElement, button);
  }
}

More examples

【讨论】:

  • 感谢您的回答,但我之前已经检查过此解决方案。它并没有让它变得更容易。而 y 是不是比 HTMLElement 好
  • 这样更好,因为现在 Angular 已经知道 DOM 的变化了。只是将它附加到 DOM 角度是不知道的。
  • 它的确切优势是什么。
  • 我只是解释了
  • 我已经实现了elemenrref的内部元素并添加了业务逻辑。所以我需要知道的是添加renderer2是否会变得更容易
【解决方案3】:

The Angular documentation

Angular 元素 是封装为 自定义元素(也称为 Web 组件)的 Angular 组件

因此,您可以使用创建要添加的元素

  1. document.createElement('elementName') 如果是autonomous custom element,或者
  2. document.createElement('baseElementName', {is: 'elementName'}) 如果是customized built-in element

您可以使用container.insertAdjacentElement(position, element) 将您创建的元素插入到container 元素中,如here 所述。

【讨论】:

  • 这正是我所做的,但我想知道的是更好的解决方案。请正确阅读问题
  • @SachithRukshan 我相信这与writing the html as the string and passing it to the innerHTML 完全不同
【解决方案4】:
import { AfterContentInit, Component, ElementRef } from '@angular/core';

@Component({
    selector: 'app-root',
    template: `
    <h1>My App</h1>
    <pre>
      <code>{{ node }}</code>
    </pre>
  `
})
export class AppComponent implements AfterContentInit {
  node: string;

  constructor(private elementRef: ElementRef) { }

  ngAfterContentInit() {
    const tmp = document.createElement('div');
    const el = this.elementRef.nativeElement.cloneNode(true);

    tmp.appendChild(el);
    this.node = tmp.innerHTML;
  }

}

【讨论】:

  • 我在进行一些跟踪时发现了这一点。希望你觉得它有用
  • 您好 Amrish,感谢您提供帮助。可以解释一下它如何帮助我解决问题。
  • @AmrishkhanSheik 嗨,欢迎来到 Stackoverflow。当您发布答案时,建议您也提供解释。只是一个代码围栏并不能解释为什么或如何与答案相关。见:How do I write a good answer?
【解决方案5】:

鉴于该组件已在 window.customElements 中注册,
根据 Angular 文档,它可能是,
你可以这样做:

var element = document.createElement("div");

var comp= document.createElement("your-component")
/*
optionally set component attributes or anything else
you also have access to the component's properties here
comp.setAttribute("name",value)
console.log(comp.exampleProperty)
*/
element.appendChild(comp)

【讨论】:

    【解决方案6】:

    您想要实现的目标是不可能的,并且违反了最佳实践。相反,您必须使用条件显示该组件。您可以在服务中创建变量,并根据该值显示或循环组件。

    【讨论】:

    • 如果可以像我喜欢的那样做,但使用的插件只提供 HTMLElement
    猜你喜欢
    • 2013-10-22
    • 2012-07-23
    • 2019-03-28
    • 2010-10-19
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多