Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to share mixins across web components (and imports) in Polymer?

As a follow up to How to extend multiple elements with Polymer and Polymer multiple inheritence/composition, based on their answers, I wonder if it's possible to share mixins across multiple web components (and multiple imports) to reuse functionality.

Mixins seem to be the only way to share functionality across multiple custom elements. However, it seems like you can only use a mixin within one import. Which means, if you have a mixin, that gives a web component a specific functionality (let's say draggable), it's not possible to mix it into the construction of your Polymer element if it's not in the same import.

Maybe I got something wrong there but if not, it feels like that the use of mixins isn't very flexible either, because I'm still not able to share functionality across web components.

UPDATE:

As Scott Miles pointed in his comments out, it is possible to use mixins in more than one import. I just wasn't sure how to do that and it turns out, that it's very straight forward.

Let's say we have a mixin that should be shared across multiple components, but components are distributed over many imports. All one has to do is to define that mixin in its own import on the window object. So for example:

shared.html

<script>
  window.sharedMixin = {
    // shared functionality goes here
  };
</script>

And then, reusing that mixin in another component in another import, is as simple as importing shared.html.

my-component.html

<link rel="import" href="path/to/shared.html">

From that point on, sharedMixin is available as global object within that import:

Polymer('my-component', Platform.mixin({
  // my-component logic
}, sharedMixin);

I hope that helps others. I'll write a blog post about that and will link it here.

UPDATE 2

I've written a blog post here: http://pascalprecht.github.io/2014/07/14/inheritance-and-composition-with-polymer/

like image 586
Pascal Precht Avatar asked Jun 12 '14 09:06

Pascal Precht


2 Answers

To use a global-like component is the recommended way to go.
make a <name-you-like> and use get/set to change it (also you can use attributes although they are only sad strings).

from Polymer API guide you'll see working (good looking) examples like this:

 <polymer-element name="app-globals">
  <script>
  (function() {
    // these variables are shared by all instances of app-globals
    var firstName = 'John';
    var lastName = 'Smith';

    Polymer({
       ready: function() {
         // copy global values into instance properties
         this.firstName = firstName;
         this.lastName = lastName;
       }
    });
  })();
  </script>
</polymer-element>

And play with them using javascript es5 getters/setters such as in the above mentioned case would look like

 <polymer-element name="app-globals">
  <script>
  (function() {
    // these variables are shared by all instances of app-globals
    var firstName = 'Arnold';
    var lastName = 'Schwarzenegger';

    Polymer({
       ready: function() {
         // copy global values into instance properties
         this.firstName = firstName;
         this.lastName = lastName;
       },
       get fullTerminatorName() {
         return this.firstName + ' ' + this.lastName;
       }
    });
  })();
  </script>
</polymer-element>

I'll be back.

like image 141
Caio Wilson Avatar answered Oct 05 '22 02:10

Caio Wilson


This is now addressed by the Behaviors feature.

Example:

my-behavior.html:

<script>
  MyBehavior = {
    properties: {},
    listeners: [],
    _myPrivateMethod: function(){}
    // etc.
  };
</script>

my-element.html:

<link rel="import" href="my-behavior.html">

<script>
  Polymer({
    is: 'my-element',
    behaviors: [MyBehavior]
  });
</script>

my-other-element.html:

<link rel="import" href="my-behavior.html">

<script>
  Polymer({
    is: 'my-other-element',
    behaviors: [MyBehavior]
  });
</script>
like image 45
Zikes Avatar answered Oct 05 '22 04:10

Zikes