如何将组件添加到ElementRef中?

11

我想将一个组件作为子元素添加到一个 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。是否有更好的选项?


你能解释得更详细一些吗? - Developer
你的需求是什么?你想做的是不可能的。 - PierreD
你能否提供一个可能的替代方案? - Sachith Rukshan
5
你可以查看 https://angular.cn/guide/dynamic-component-loader 和 https://dzone.com/articles/how-to-dynamically-create-a-component-in-angular,这些资源可以帮助你动态创建 Angular 组件。 - Caro
尝试过了,但没有起作用 @Caro - Sachith Rukshan
@Caro是正确的。你应该使用动态组件创建,这正是它的目的。如果你尝试过但无法使其工作,我建议你发布你的尝试,并让我们来帮助你修复它。 - ethanfar
5个回答

16

在我的一个项目中,我通过类似的方法实现了与您要求类似的功能。如果有帮助,请告诉我。

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访问实例,对吗? - Sachith Rukshan
1
@SachithRukshan 是的 - prabhatojha
1
要获取domElem,我们可以使用componentRef.location.nativeElement; - Alessandro Kreslin

6
你也许可以使用 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);
  }
}

更多示例


谢谢回答,但我之前已经检查过这个解决方案。它并没有使问题更容易解决。另外,为什么它比HTMLElement更好呢? - Sachith Rukshan
2
这样做更好,因为现在Angular知道DOM的变化。只是将其附加到DOM中,Angular并不知道它的存在。 - Robin Dijkhof
它的确切优势是什么? - Sachith Rukshan
4
我刚才确实解释了。 - Robin Dijkhof
我已经实现了elemenrref的内部元素,并添加了业务逻辑。所以我想知道是否添加renderer2会使它更容易。 - Sachith Rukshan

1

Angular文档中提到:

Angular elements 是打包为 自定义元素(也称为 Web 组件)的 Angular 组件。

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

  1. document.createElement('elementName') (如果它是 独立自定义元素),或者
  2. document.createElement('baseElementName', {is: 'elementName'}) (如果它是一个 自定义内置元素)。

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


那正是我所做的,但我想知道是否有更好的解决方案。请仔细阅读问题。 - Sachith Rukshan
1
@SachithRukshan 我相信这与“将HTML作为字符串编写并将其传递给innerHTML”完全不同。 - Dane Brouwer

0
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 khan Sheik
嗨,Amrish,感谢您的帮助。您能否解释一下它如何帮助我的问题? - Sachith Rukshan
@AmrishkhanSheik 您好,欢迎来到Stackoverflow。当您发布答案时,建议您同时提供解释。仅有代码框无法解释为什么或如何与答案相关。请参阅:如何撰写好的答案? - Dane Brouwer

0

假设该组件已在 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)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接