0

I'm using LitElement webcomponents with an angular application

I implemented two ways data binding with a CustomEvent dispatch but I would like to use angular's banana-in-a-box syntax sugar.

Example : this stackblitz : a webcomponent with an integer property that could be incremented within the webcomponent itself

Current syntax :

<hello-world [counter]="counter" (counterChange)="counter = $event.detail.value"></hello-world>

Syntax I want to achieve :

<hello-world [(counter)]="counter"></hello-world>

When I increment from within the webcomponent the event is caught by angular because the name of the event corresponds to the name of a property + Change (counterChange) but the whole CustomEvent is assigned to the value instead of the $event.detail.value value

From what I read in the documentation, angular achieves this with the EventEmitter model, which according to the code are rxjs Subjects, I'll try to go this route instead of the CustomEvent route.

If anybody has any clue on how to achieve this I'd love some tips :)

Thanks !

Alfred
  • 649
  • 5
  • 11

2 Answers2

0

In the webcomponent hello-word use

in html component use button with:

button --> (counter)="handleCounter($event)"

@Output() counter = new EventEmitter<number>();

// .ts
handleCounter(ev){
    ev.stopPropagation();
    ev.preventDefault();
    //Here you need to increment and set value  
    this.counter.emit(value);
  }

and use the component:

<hello-world (counter)="onValueCounter($event)"></hello-world>

//.ts

  @Output() onCounter = new EventEmitter<any>();

  onValueCounter(term){
    this.onCounter .emit(term);
    console.log(term);
  }

I hope this help you!!!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
corsaro
  • 731
  • 1
  • 9
  • 24
  • Hi thanks for your answer, however I'm not using angular for the hello-world component but a webcomponent (LitElement) cf the stackblitz in my post. I edited the post for clarity – Alfred Feb 13 '20 at 11:31
0

Might be that you could use some part of my solution. I was struggling with the same issue with my Stencil project (angular-output-target), only difference was toggling a boolean for the visibility of a modal.

I went with a solution where i created a new directive with the component library tag as the selector. Then applied hostlistners to the event(s) and emitted out the new value with the Angular EventEmitter.

import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';

@Directive({
  // eslint-disable-next-line @angular-eslint/directive-selector
  selector: 'library-modal',
})
export class ModalDirective {
  @Input() open: boolean = false;
  @Output() openChange: EventEmitter<boolean> = new EventEmitter();

  @HostListener('afterOpen', ['$event.detail'])
  @HostListener('afterClose', ['$event.detail'])
  updateOpen(event) {
    this.openChange.emit(event);
  }
}

I was then able to use the component with CustomEvent and two-way binding after importing the new directive to the correct module.

<library-modal [(open)]="openModalBoolean">
  <p>Content</p>
</library-modal>

Could be too late for your project, but I hope it can help others :)

Breilid
  • 56
  • 4