9

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/

Community
  • 1
  • 1
Pascal Precht
  • 8,803
  • 7
  • 41
  • 53
  • Why not have each component declare a shared component Something like http://www.polymer-project.org/docs/polymer/polymer.html#global. This is sort of what core-style does: https://github.com/Polymer/core-style/blob/master/core-style.html#L11 – ebidel Jun 13 '14 at 04:01
  • You're right, that would solve that issue. Didn't think about that `core-style` actually behaves exactly like that. I'll update my question accordingly. – Pascal Precht Jun 13 '14 at 07:06
  • This statement `you can only use a mixin within one import` is incorrect. Imports are not automatically scoped. – Scott Miles Jun 14 '14 at 23:37
  • Hey Scott. Thank so what does that mean? How can I reuse these then? – Pascal Precht Jun 15 '14 at 08:50
  • You make your mixin once, and mix it in as many times as you like. – Scott Miles Jun 17 '14 at 00:53
  • HTH http://jsbin.com/dirut/1/edit – Scott Miles Jun 17 '14 at 01:15
  • Scott, thank you for taking the time and setting up this fiddle. Unfortunately, this fiddle doesn't cover how to reuse a mixin over cross imports. Let's say I have two imports that both have a custom element each. Also, both should share functionality through a mixin. Declaring the mixin in one import makes it unavailable in the other one, am I right? – Pascal Precht Jun 17 '14 at 08:45
  • I finally understood it. Updated the question accordingly. Thank you Scott. – Pascal Precht Jun 18 '14 at 07:57
  • 1
    You should totally move your response out to an answer & mark it answered - will help others skim! – Nevir Oct 02 '14 at 19:04

2 Answers2

1

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.

Caio Wilson
  • 353
  • 2
  • 12
  • just an fyi, the ` – Jonathan Dumaine Feb 02 '15 at 18:46
  • In this case, I think, since I wrote it on november, was to increase browser compatibility. If I recall correctly firefox was screwing with it at the time. But thanks for the tip :) – Caio Wilson Feb 03 '15 at 12:00
1

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>
Zikes
  • 5,888
  • 1
  • 30
  • 44