Applying Behaviors with JS Mixins in Polymer 2
Asked Answered
P

2

8

I want a custom element I'm defining to have the Polymer.IronScrollTargetBehavior in Polymer 2.

In Polymer 1, this can be done by adding it to the behaviors array:

Polymer({
    is: 'my-element',
    behaviors: [Polymer.IronScrollTargetBehavior]
});

In the Polymer 2 upgrade guide, it says that you should:

Implement "behaviors" as mixins that return class expressions.

In the linked article, it explains how you can use the following syntax for mixins:

let MyMixin = (superclass) => class extends superclass {  
    foo() {
        console.log('foo from MyMixin');
    }
};

class MyClass extends MyMixin(MyBaseClass) {  
    /* ... */
}

I mostly get what's going on here (although I find the mixin syntax difficult to wrap my mind around), and I can get sample code to work.

What I haven't been able to do is apply this concept to Polymer.IronScrollTargetBehavior, and create a mixin for it. Since that behavior is already defined as an object, I don't know where to fit it in.

So, how do I implement the proper mixin in this scenario, or if I'm on the wrong path, how to I apply one of the defined Polymer behaviors to my custom element in Polymer 2?

Pathos answered 24/1, 2017 at 21:20 Comment(0)
A
9

You can use the Polymer 2 hybrid behaviours as mixins by extending Polymer.mixinBehaviors(behaviors, klass) where
- behaviors is the Behavior object or array of behaviors
- klass is the Element class.

i.e.

<dom-module id="element-name">
  <template><!-- ... --></template>
  <script>
    class MyElement extends Polymer.mixinBehaviors([MyBehavior, MyBehavior2], Polymer.Element) {
     static get is() { return 'element-name' }
     /* ... */
    }
    customElements.define('element-name', MyElement);
  </script>
</dom-module>

For more detailed information search the Polymer source code for mixinBehaviors method: polymer/lib/legacy/class.html

worth reading: https://www.polymer-project.org/2.0/docs/upgrade#mixins

Araujo answered 6/7, 2017 at 7:45 Comment(1)
Worth noting - to handle listeners for mixin behaviors refer to "Listener on outside elements" on polymer-project.org/2.0/docs/devguide/…Warmup
I
7

Polymer 2.0 has a compatibility layer that still supports the old Polymer function syntax. Most of the 2.0 preview elements, if not all, still retain the old syntax. The breaking changes are mostly in the dom-module markup.

If you are composing new elements, it is recommended you switch over to the class based syntax. If however you are porting 1.0 elements to 2.0 and those elements rely on Polymer behaviors, I don't think you much choice at this juncture but to retain the old syntax.

In the class-based syntax you can fluently simulate Element multiple inheritance of class mixins with something like this

    let Mixin = (superclass) => new MixinBuilder(superclass);
    class MixinBuilder {  
        constructor(superclass) {
          this.superclass = superclass;
        }

        with(...mixins) { 
         return mixins.reduce((c, mixin) => mixin(c), this.superclass);
        }
    }

    const MyMixin = subclass => class extends subclass {
      _test(){

      }
    }

    const MyMixinTwo = subclass => class extends subclass {
      _testTwo(){

      }
    }

    class MyElement extends Mixin(Polymer.Element).with(MyMixin,MyMixin2) {
       static get is() { return 'my-element' }
    }  

You can separate the MixinBuilder into its own file and then reference it as an Html Import dependency whenever composing elements that use mixins.

Inflexion answered 31/1, 2017 at 5:3 Comment(1)
That is a good description of the trade off between 1.x and 2.0-preview.Core

© 2022 - 2024 — McMap. All rights reserved.