[英]Dynamically append component to div in Angular 5
我有这个
https://angular-dynamic-component-append.stackblitz.io/
我设法动态追加一个元素,但它没有被编译。 我看过很多像这样的教程
但这并不是我真正需要的。 通常他们使用标签符号来标识容器。
我需要将一个组件附加到任何可能有自定义指令的元素上。
我还需要使用指令的绑定值来控制附加元素的[hidden]属性。
目标
<my-comp></mycomp>
预期来源
<div [myDirective]="myBoolean">
<p>some content</p>
</div>
预计汇编
<div [myDirective]="myBoolean" class="myDirectiveClass1">
<p>some content</p>
<someComponent [hidden]="myBoolean" class="myDirectiveClass2"></someComponent>
</div>
有没有办法实现这个目标?
先感谢您
这很简单。 我刚给你做了一个例子。
请阅读loader指令内的注释。
https://github.com/garapa/studying/tree/master/loader
编辑:
你组件:
export class LoaderComponent {
loading;
constructor() { }
}
你的指示
export class LoaderDirective implements OnDestroy {
private componentInstance: ComponentRef<LoaderComponent> = null;
@Input()
set appLoader(loading: boolean) {
this.toggleLoader(loading);
}
constructor(
private viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver
) { }
toggleLoader(loading: boolean) {
if (!this.componentInstance) {
this.createLoaderComponent();
this.makeComponentAChild();
}
this.componentInstance.instance.loading = loading;
}
private createLoaderComponent() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(LoaderComponent);
this.componentInstance = this.viewContainerRef.createComponent(componentFactory);
}
private makeComponentAChild(){
const loaderComponentElement = this.componentInstance.location.nativeElement;
const sibling: HTMLElement = loaderComponentElement.previousSibling;
sibling.insertBefore(loaderComponentElement, sibling.firstChild);
}
ngOnDestroy(): void {
if (this.componentInstance) {
this.componentInstance.destroy();
}
}
}
你的模块
@NgModule({
...
entryComponents: [
LoaderComponent
]
})
这是我开始工作的方式
import { Renderer2, Directive, Input, ElementRef, OnChanges, ViewEncapsulation } from "@angular/core"; import { MatSpinner } from "@angular/material"; @Directive({ selector: "[myDirective]" }) export class MyDirective { @Input() set myDirective(newValue: boolean) { console.info("myDirectiveBind", newValue); if (!!this._$matCard) { const method = newValue ? "removeClass" : "addClass"; this.renderer[method](this._$matCard, "ng-hide"); } this._myDirective = newValue; } private _myDirective: boolean; private _$matCard; constructor(private targetEl: ElementRef, private renderer: Renderer2) { this._$matCard = this.renderer.createElement('mat-card'); const matCardInner = this.renderer.createText('Dynamic card!'); this.renderer.addClass(this._$matCard, "mat-card"); this.renderer.appendChild(this._$matCard, matCardInner); const container = this.targetEl.nativeElement; this.renderer.appendChild(container, this._$matCard); } } import { Component, ElementRef, AfterViewInit, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'card-overview-example', templateUrl: 'card-overview-example.html', styleUrls: ['card-overview-example.css'] }) export class CardOverviewExample { hideMyDirective = !1; constructor(private _elementRef: ElementRef) { } getElementRef() { return this._elementRef; } ngAfterViewInit() { let element = this._elementRef.nativeElement; let parent = element.parentNode; element.parentNode.className += " pippo"; } }
.ng-hide { display: none; }
<mat-card>Simple card</mat-card> <div class="text-center"> <button (click)="hideMyDirective = !hideMyDirective"> Toggle show dynamic card </button> </div> <br /> <span>hideMyDirective: {{hideMyDirective}}</span> <hr /> <div class="myDiv" [myDirective]="hideMyDirective"> <ul> <li>My content</li> </ul> </div>
在要插入组件的组件html文件中:
<div #target>
</div>
在要插入组件的组件ts文件中:
'Component_to_insert' - >是要插入另一个组件内的组件。
import { Component_to_insert } from 'path';
import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver, AfterViewInit } from '@angular/core';
@Component({
selector: 'component-name',
templateUrl: 'component.html',
styleUrls: ['component.scss'],
entryComponents: [Component_to_insert]
})
export class ManagetemplatesPanelComponent implements AfterViewInit {
@ViewChild('target', { read: ViewContainerRef }) entry: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
ngAfterViewInit() {
this.createComponent();
}
createComponent() {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(Component_to_insert);
const componentRef = this.entry.createComponent(factory);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.