0

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

DilumN
  • 2,889
  • 6
  • 30
  • 44
Brk
  • 1,247
  • 2
  • 23
  • 55
  • 2
    StackOverflow isn't a place for you to ask people to write your code for you. Show us what you've attempted and make a solid effort – Jesse Carter Feb 17 '17 at 20:44
  • ok I will upload it right a way, the code isn't even works – Brk Feb 17 '17 at 20:45
  • 1
    instead of trying to close this thread,why not helping each other. I am making a solid effort in trying to understand if this topic is even possible in angular 2. If not I won't migrate to angular 2 or use it. I have passed on my examples in the internet and no solid answer for my case. – Brk Feb 17 '17 at 20:54

1 Answers1

2

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, i.e. 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 (i.e. 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 (i.e. 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

Community
  • 1
  • 1
A. Tim
  • 3,046
  • 1
  • 13
  • 15
  • Thanks tim for the quick answer, but is looks to me that accroding to attached answer, reflect metdata is for inheritance and not for creating dynamic component. – Brk Feb 17 '17 at 21:01
  • I got you r explanation right, but I am looking for example which clear me out how to use such tool like reflect metadata – Brk Feb 17 '17 at 21:02
  • Ok, probably I misunderstood your question. I thought you want to share common functions between components, instead of coding it on the fly). – A. Tim Feb 17 '17 at 21:03
  • You are right, I want to have coding on the fly like a code generator but a simple one. Thanks for your answer and your effort.sorry if I wasn't clear enough – Brk Feb 17 '17 at 21:04
  • try http://blog.rangle.io/dynamically-creating-components-with-angular-2/ and http://stackoverflow.com/questions/39678963/load-existing-components-dynamically-angular-2-final-release – A. Tim Feb 17 '17 at 21:09