简体   繁体   中英

Create a Dynamic Component in Angular 2

Hey I am new to angular 2, I have played with angular 2 for the past week and wondered if it possible to generate a dynamic component with a dynamic template and dynamic styles. This means that the follwoing should be like this

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

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

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

is it possible to do it in angular 2, I remember that such this is maybe possible in angular 1.

Any Help will be appreciated(Escpecially plunkers with simple code)

This is what I have achieved so far: try using 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();
    }
}

Here is a plunker which enables to created dynamic component, I don't know if creating dynamic css is possible,I would be pleased if some can I answer my question: http://plnkr.co/edit/ZXsIWykqKZi5r75VMtw2?p=preview

With TypeScript and latest version of Angular2 (I believe that feature has been released in 2.4.0) you can create 1 base component and then extend it. All decorators/annotations on properties ( @Input/@Output/@ViewChild ) will be copied. However, you must specify for each ancestor @Component properties, ie you cannot overwrite only selector , but everything. That is RIGHT approach.

Another approach -> use reflect-metadata to update decorators on Component classes (probably that is what you are looking for, as it that case you can overwrite 1 property at time), but be careful to export (ie make public) all Components/Directives/Services that are used inside of Component that you want to overwrite. For example, some libraries have multiple Components, and some of them are supposed to be used only internally (ie there is no way to import it into your module in normal way... however, you can try providers ). If you try to "overwrite", say, css with reflect-metadata and it uses internal components -> angular/typescript will crash, as it cannot resolve "internal" stuff. You can start with this answer: StackOverflow

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM