Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Angular<->Polymer template data host bindings #36

Closed
hotforfeature opened this issue Jun 21, 2017 · 4 comments
Closed

Support Angular<->Polymer template data host bindings #36

hotforfeature opened this issue Jun 21, 2017 · 4 comments
Assignees
Labels

Comments

@hotforfeature
Copy link
Owner

Currently it's possible to bind events to a polymer template:

@Component({
  template: `
    <template ngNonBindable [polymer]="this">
      <paper-checkbox on-checked-changed="angularMethod"></paper-checkbox>
    </template>
  `
})
export class MyComponent {
  angularMethod(e: CustomEvent) {
    console.log('click', e);
  }
}

Though it is not possible to bind data properties to any elements in a Polymer template. This is a pain point in particular for vaadin-grid's selection column.

<!-- This is fine to bind, we're not in a Polymer template -->
<vaadin-grid-selection-column [(selectAll)]="{{angularSelectAll}}" emitChanges>
  <template class="header">
    <!-- This wants to bind to a "host" element property, but it can't :( -->
    <paper-checkbox checked="{{angularSelectAll}}"></paper-checkbox>
  </template>
  <template>
    <!-- Model template, this is fine -->
    <paper-checkbox checked="{{selected}}"></paper-checkbox>
  </template>
</vaadin-grid-selection-column>

In Polymer, the host element's template sets up bindings on its children by setting the __dataHost property. We're emulating this in the polymer template directive, though we only get the host after ngOnInit(), which can fire after Polymer has already done some binding (looking at you again vaadin-grid...)

The TL;DR is I want this Polymer template:

<dom-module id="my-component">
  <template>
    <paper-checkbox checked="{{polymerProperty}}"></paper-checkbox>
  </template>
  <script>
    class MyComponent extends Polymer.Element {
      static get is() { return 'my-component'; }
      static get properties() {
        return {
          polymerProperty: Boolean
        };
      }
    }
  </script>
</dom-module>

To match this Angular template in behavior:

@Component({
  template: `
    <template ngNonBindable>
      <!-- Automagic Polymer template binding -->
      <paper-checkbox checked="{{angularProperty}}"></paper-checkbox>
    </template>
  `
})
export class MyComponent {
  @PolymerChanges() angularProperty: boolean;
}

I think this can be achieved by going through all the children of the Angular component and seeing the __dataHost property like Polymer does in setupBindings(). Ideally this will completely eliminate the need for <template polymer>.

@hotforfeature
Copy link
Owner Author

To those subscribing to this issue, this feature is now implemented! It still needs testing before I bundle it in the next release though, a lot of things changed to support property binding.

The good news is that with this feature, <vaadin-grid> is working pretty nicely :)

@hotforfeature
Copy link
Owner Author

Available in 1.3.0-beta.0. Feature complete, just needs testing before I consider it stable. Open an issue if you find any problems with it!

@Analect
Copy link

Analect commented Jul 25, 2017

@hotforfeature ... do you have a worked example anywhere with this pattern implemented? Thanks.

@hotforfeature
Copy link
Owner Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants