1

My custom Polymer webcomponents malfunction with Angular2. I had to wrap them in custom directive (which delays the rendering of web components until the are inserted into the DOM by angular).

Wrapping works like that:

<my-custom-wrapper component="custom-fancy-element"></my-custom-wrapper>

What basically happens is that directive <my-custom-wrapper> is being hidden and I insert the <custom-fancy-element> before this hidden element. <custom-fancy-element> is correctly shown on the web page. The problem is when I want to apply event binding attribute like (click)="someFunction()".

This is what I do:

<my-custom-wrapper component="custom-fancy-element" (click)="someFunction()">
</my-custom-wrapper>

And this is what I want as a result:

<custom-fancy-element (click)="someFunction()"></custom-fancy-element>

How is it possible to fetch this event binding attribute from inside TypeScript and later on add it to the newly created html element? I tried .setAttribute("on-click", "someFunction($event)"); but angular doesn't recognize it.

Below is a code snippet of how I handle other attributes (like value="something" class="alert green-stuff" that I want to be added to the newly created HTML element.

constructor(@Attribute('component') component: string, element: ElementRef) {
  this.component = component;
  this.element = element;

  var my_new_component = document.createElement(this.component);
  if (my_new_component.constructor !== HTMLUnknownElement) {
    if (this.element.nativeElement.getAttribute("value")){
      my_new_component.setAttribute("value", this.element.nativeElement.getAttribute("value"));
    }
    if (this.element.nativeElement.getAttribute("class")) {
      var myComponentClasses = this.element.nativeElement.getAttribute("class").split(" ");
      for (var i = 0; i < myComponentClasses.length; i++) {
        my_new_component.className += " " + myComponentClasses[i];
      }
    }
    this.webcomponent = my_new_component; // Which is just:
               // <custom-fancy-element class="blue-pattern" value="some"></custom-fancy-element>
}

}

And later on I insert HTML element before my directive like that:

ngOnInit() {
  var parentNode = Polymer.dom(this.element.nativeElement).parentNode;
  if (parentNode) {
    Polymer.dom(parentNode).insertBefore(this.webcomponent, this.element.nativeElement);
  }
}

I guess, getting and setting attribute in Angular 1 would be possible with

.directive('someDirective', function() {
   return {
     ...
     link: function (scope, element, attributes) {
       //assign attribute to web component
     }
}

but how to do it in Angular2 and TypeScript?

Astrowie
  • 195
  • 2
  • 17

1 Answers1

2

This is not supported. You can't add (click) or (keyup) dynamically to the DOM. You can get hold of an element and use addEventListener(...)

Angular2 binding syntax only works when statically added to a components template.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • The problem is, how do I check if `` directive has an event binding attribute like `(click)="someFunction()"` so I could add event listener for click to corresponding webcomponent? – Astrowie Aug 31 '16 at 06:34
  • Sorry, I don't really understand the question. `(click)="someFunction()"` is some declarative binding that gets removed when Angular compiles the template (offline template compiler or at runtime when it creates the component) and replaces it by `addEventListener('click', ...)`. When the component exists in the DOM there won't by any `(click)="..."` anymore. – Günter Zöchbauer Aug 31 '16 at 06:37
  • I don't really want to check for "physical" existance of `(click)="someFunction()"` between some html tags. I want to check if there is an event attached to it, like (click) or (keyup). Is it possible? – Astrowie Aug 31 '16 at 06:51
  • I guess not http://stackoverflow.com/questions/11455515/how-to-check-whether-dynamically-attached-event-listener-exists-or-not – Günter Zöchbauer Aug 31 '16 at 06:52