Jakub Matwiejew
Jakub Matwiejew

Reputation: 107

Using @Output() with dynamically added components

I'm creating a shopping list. It will be made out of two components: shopping-cart and shopped-item.

The shopping-cart has a button that dynamically adds a new shopped-item in a <div>.

The shopped-item after being added can be marked as active or unmarked so I created an EventEmmiter that changes the value marked/unmarked. But since the component is added dynamically I don't know where to add it in shopping-cart component...

How can I make it work like this:

After the shopped-item is added it appears in an array with marked/unmarked value that changes when it's clicked in the shopped-item component?

Cheers!

Shopped-item.ts file:

export class ShoppedItemComponent implements OnInit {

  _ref:any;   
  removeObject(){
    this._ref.destroy();
  } 

  @Output() statusChange = new EventEmitter<{status: boolean}>();

  marked;

  unmarkItem () {
    this.marked = !this.marked;
    this.statusChange.emit({status: this.marked});
  }


  constructor() {    
   }

}

Shopping-cart.ts file:

export class ShoppingCartComponent implements OnInit {

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

  constructor(
    private resolver: ComponentFactoryResolver
  ) { }

  isMarked = [];

  shoppedItemStatus (statusChange: {status: boolean}) {
    this.isMarked.push({
      status: statusChange.status
    })
  }

  addItem() {
    const shoppedItem = 
      this.resolver.resolveComponentFactory(ShoppedItemComponent);
    const component = this.boughtItems.createComponent(shoppedItem);
    component.instance._ref = component;        
  }

}

Shopping-cart.html file:

  <div #boughtItems>
    <button (click)="addItem()">ADD</button>
  </div>

Upvotes: 0

Views: 56

Answers (1)

eprats
eprats

Reputation: 345

Why are you creating the components by hand?

I would use a *ngFor in the view

<div #boughtItems>
  <button (click)="addItem()">ADD</button>
  <div *ngFor="let item of items">
    <app-item-bought xxxx="item" (markToggle)="myFunction(item)"></app-item-bought>
  </div>
</div>

where xxxx is a field of your class ShoppedItemComponent decorated with Input('xxxx'). (markToggle) is the name of the emitter in ShoppedItemComponent and myFunction(item) is a function defined in the Shopping-cart that will receive the item that has fired the event.

Hope it helps!

Upvotes: 1

Related Questions