在Angular 2中创建动态组件

时间:2017-02-17 20:42:04

标签: javascript angular

嘿,我是角度2的新手,过去一周我玩过角度2,想知道是否可以使用动态模板和动态样式生成动态组件。这意味着下面的内容应该是这样的

@Component({
    // 2a
    selector: 'dynamic placeholder',

    // 2b
    styles: [`dynamic styles`] 

    // 2c
    template: `dynmic template`
})

是否可以在角度2中进行,我记得这可能在角度1中可能。

任何帮助将不胜感激(特别是具有简单代码的掠夺者)

这是我到目前为止所取得的成就:尝试使用ComponentFactoryResolver:

@NgModule({
    imports: [BrowserModule],
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {
}

@Component({
    selector: 'my-app',
    template: `
        <div>Hello, world!</div>
    `
})
export class AppComponent {
}

@NgModule({
    declarations: [HomeComponent],
    exports: [HomeComponent]
})
export class HomeModule {
}

@Component({
    selector: 'home',
    template: `
        <div>This is home</div>
    `
})
export class HomeComponent {
}

@Component({
    selector: 'hello-world',
    template: `
        <div>
            Hello, world!, {{name}}
            The answer is: {{getAnswer()}}
        </div>
    `
})

export class HelloWorldComponent implements AfterViewInit {
    private name:string = 'You';

    constructor(private helloWorldService: HelloWorldService) {
    }

    ngAfterViewInit(): void {
        this.name = 'Me';
    }

    private getAnswer() {
        return this.helloWorldService.giveMeTheAnswer();
    }
}

@NgModule({
    declarations: [HomeComponent, HelloWorldComponent],
    providers: [HelloWorldService],
    exports: [HomeComponent]
})
export class HomeModule {
}

@Component({
    selector: 'home',
    template: `
        <button (click)="sayHello()">Say hello</button>
        <div>This is home</div>
    `
})

export class HomeComponent {
    constructor(private componentFactoryResolver: ComponentFactoryResolver,
                private viewContainerRef: ViewContainerRef) {
    }

    private sayHello() {
        const factory = this.componentFactoryResolver.resolveComponentFactory(HelloWorldComponent);
        const ref = this.viewContainerRef.createComponent(factory);
        ref.changeDetectorRef.detectChanges();
    }
}

这是一个能够创建动态组件的plunker,我不知道是否可以创建动态css,如果有人可以回答我的问题,我会很高兴: http://plnkr.co/edit/ZXsIWykqKZi5r75VMtw2?p=preview

1 个答案:

答案 0 :(得分:2)

使用TypeScript和最新版本的Angular2(我相信该功能已在2.4.0中发布),您可以创建1个基本组件,然后对其进行扩展。将复制属性(@Input/@Output/@ViewChild)上的所有装饰器/注释。但是,您必须为每个祖先@Component属性指定,即您不能只覆盖selector,而是覆盖所有内容。这是正确的做法。

另一种方法 - &gt;使用reflect-metadata来更新Component类的装饰器(可能就是你正在寻找的东西,因为在这种情况下你可以覆盖1个属性),但要小心export(即公开)所有在要覆盖的Component内部使用的组件/指令/服务。例如,某些库有多个组件,其中一些只能在内部使用(即无法以正常方式将其导入模块中......但是,您可以尝试providers)。如果您尝试&#34;覆盖&#34;,例如,css与reflect-metadata并且它使用内部组件 - &gt; angular / typescript会崩溃,因为它无法解决&#34;内部&#34;东西。您可以从这个答案开始:StackOverflow