1

I have components added dynamically into a page through a component factory. How can i bind the click event of each to a function (passing an id as argument for each)?. This is my code:

component/card-one/card-one.html:

<ion-card>
  <ion-card-header>
    {{ title }}
  </ion-card-header>

  <ion-card-content>
    {{ data }}
  </ion-card-content>
</ion-card>

component/card-one/card-one.ts:

import { Component, Input } from '@angular/core';
import { ProcessComponent } from '../process';

@Component({
  selector: 'card-one',
  templateUrl: 'card-one.html'
})
export class CardOneComponent implements ProcessComponent {

  @Input() data: any;
  @Input() title: any;

  constructor() {}

}

And in the page/home/home.ts:

import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { NavController } from 'ionic-angular';
import { ProcessProvider } from '../../providers/process/process';
import { ProcessComponent } from '../../components/process';
import { CardOneComponent } from '../../components/card-one/card-one';
import { CardTwoComponent } from '../../components/card-two/card-two';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  @ViewChild('processContainer', { read: ViewContainerRef }) container;

  constructor(public navCtrl: NavController, private processProvider: ProcessProvider, private resolver: ComponentFactoryResolver) { }

    clickOnComponent(component){
        // 
    }

    ionViewDidLoad() {

        let items = [
            {
                component: CardOneComponent,
                desc: 'Mighty first step',
                title: 'Hello'
            },
            {
                component: CardTwoComponent,
                desc: 'Always first looser',
                title: 'Hello'
            }
            ]

        for (let card of cards) {
        const factory = this.resolver.resolveComponentFactory(card.component);
        let componentRef = this.container.createComponent(factory);

        (<ProcessComponent>componentRef.instance).data = card.desc;
        (<ProcessComponent>componentRef.instance).title = card.title;
        }
    }
}

Thanks!

1
  • 1
    Can you share full code? Your current code shared does not provide a good clarity re what you want Commented Dec 12, 2018 at 14:05

1 Answer 1

1

you can defined a @HostListener in each of these component this will resolve that click on the component it self

example

export class CounterComponent  {

  public counter:number = 0


  @HostListener('click') onClick() { 
    this.counter++;
  }

}

  @HostListener('click') onClick() { 
    this.counter++;
  }

check this stackblitz demo 👍

Updated 🚀🚀

I 'm still not sure what you said about add click event to to create components but maybe this will help you can create an output property and subscribe to this property and this property will fire/emit every time the user click on the component

see this demo where I create a component dynamic like you and pass a data and handle the click event on that component

Counter Component

export class CounterComponent  {

 @Input() counter:number = 0;
 @Output() onClick=new EventEmitter(); 


  @HostListener('click') emitClick() { 
    this.counter++;
    this.onClick.emit(`this user click ${this.counter}`);
  }

}

App Component

@Component({
  selector: 'my-app',
  template: `
    <template #counters></template>
  `,
})

export class App {
  @ViewChild("counters", { read: ViewContainerRef }) container;
  componentRef: ComponentRef<any>;

  constructor(private resolver: ComponentFactoryResolver) { }

  ngOnInit() {
    this.container.clear();
    const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(CounterComponent);
    this.componentRef = this.container.createComponent(factory);
    this.componentRef.instance.counter = 10;
    this.componentRef.instance.onClick.subscribe(data => this.handler(data));
  }

  handler(countData) {
    console.log(`handler : data => ${countData}`)
  }

  ngOnDestroy() {
    this.componentRef.destroy();
  }
}

stackblitz demo 🎉🎉

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.