5

I have a login component, and I'd like to make the login status available for other components in my application.

Can anyone provide working code or examples?

I need some sort of binding or eventing at least, so that when the login status changes, the UI of these other interested components can be updated accordingly.

Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
Janos
  • 1,987
  • 3
  • 17
  • 24

4 Answers4

2

Create a property that represents the status in your login component and set notify: true. Use data-binding in your login component and any other components that use that status.

<login-component status="{{status}}"></login-component>
<other-component login="{{status}}"></other-component>

If you use your components outside of a Polymer template, make use of autobind by wrapping them in a <template is="dom-bind">.

<template is="dom-bind">
    <login-component status="{{status}}"></login-component>
    <other-component login="{{status}}"></other-component>
</template>
Maria
  • 5,574
  • 1
  • 29
  • 39
  • this doesn't seem to work. can you refer me to a simple example where one component can see another one's property? – Janos Jul 23 '15 at 12:36
  • unfortunately the binding section in Polymer doc (https://www.polymer-project.org/1.0/docs/devguide/data-binding.html) seems to only talk about binding inside a component, and not between components. – Janos Jul 23 '15 at 12:39
  • see also: http://stackoverflow.com/questions/23522037/data-binding-between-nested-polymer-elements – Janos Jul 23 '15 at 12:41
  • This may be a good enough workaround: http://stackoverflow.com/questions/27721040/2-way-data-binding-between-a-polymer-component-and-a-model - The two components would communicate via a model property. I will try this out and update this page with my results. – Janos Jul 23 '15 at 12:44
  • I have a small working example in this Plunker: http://plnkr.co/edit/MZL3XrcKvF3E5aWiBB8I?p=preview – Maria Jul 23 '15 at 13:04
  • 1
    Data-binding between components outside of a Polymer template is described in the auto-binding section in the doc: https://www.polymer-project.org/1.0/docs/devguide/templates.html#dom-bind – Maria Jul 23 '15 at 13:11
  • thanks for the example. I must admit, I don't quite understand why login-component status="{{status}}" is needed? If I remove this, it's only the login component that keeps updating properly. – Janos Jul 25 '15 at 15:43
  • in the index page I can replace the {{status}} to be any arbitrary name, and the example works unless I use the same name for the two components. – Janos Jul 25 '15 at 15:56
  • 1
    I think I understand now what's going on here. By specifying a variable for the status attribute you let Polymer bind the login component's status property to that variable you specified. You can than then provide that same variable as input to other components. Interesting :) Of course, these components must then be on the same page. – Janos Jul 25 '15 at 16:01
  • For situations where this kind of colocation of components are not feasible, I'm experimenting with PostalJS - looks quite cool. – Janos Jul 25 '15 at 17:56
1

See this Plunker example (by @nazerke) demonstrating one component observing another's property.

http://plnkr.co/edit/p7R8BqJJfoYMVA3t3DbX?p=preview

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="parent-element.html">
  <link rel="import" href="first-child.html">
  <link rel="import" href="second-child.html"> </head>

<body>
  <parent-element></parent-element>
</body>

</html>
parent-element.html
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">
<dom-module id="parent-element">
  <template>
    <first-child prop={{value}}></first-child>
    <second-child feat1={{prop}}></second-child> In parent-element
    <h1>{{value}}</h1> </template>
  <script>
    Polymer({
      is: "parent-element",
      properties: {
        value: {
          type: String
        }
      },
      valueChanged: function() {
        console.log("value changed");
      }
    });
  </script>
</dom-module>
first-child.html
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">
<dom-module id="first-child">
  <template>
    <p>first element.</p>
    <h2>{{prop}}</h2> </template>
  <script>
    Polymer({
      is: "first-child",
      properties: {
        prop: {
          type: String,
          notify: true
        }
      },
      ready: function() {
        this.prop = "property";
      }
    });
  </script>
</dom-module>
second-child.html
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">
<dom-module id="second-child">
  <template>
    <p>Second element.</p>
    <h2>{{feat1}}</h2> </template>
  <script>
    Polymer({
      is: "second-child",
      properties: {
        feat1: {
          type: String,
          notify: true,
          value: "initial value"
        }
      },
      ready: function() {
        this.addEventListener("feat1-changed", this.myAct);
      },
      myAct: function() {
        console.log("feat1-changed ", this.feat1);
      }
    });
  </script>
</dom-module>
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
  • Thanks, the example looks interesting, I'll try to take it a bit further by adding some event handler that would change the property driven by a user action – Janos Jul 25 '15 at 15:49
1

You can use <iron-localstorage> as described here.

<dom-module id="ls-sample">
  <iron-localstorage name="my-app-storage"
    value="{{cartoon}}"
    on-iron-localstorage-load-empty="initializeDefaultCartoon"
  ></iron-localstorage>
</dom-module>

<script>
  Polymer({
    is: 'ls-sample',
    properties: {
      cartoon: {
        type: Object
      }
    },
    // initializes default if nothing has been stored
    initializeDefaultCartoon: function() {
      this.cartoon = {
        name: "Mickey",
        hasEars: true
      }
    },
    // use path set api to propagate changes to localstorage
    makeModifications: function() {
      this.set('cartoon.name', "Minions");
      this.set('cartoon.hasEars', false);
    }
  });
</script>
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
  • This will have the unfortunate side effect of persisting the value across page loads, since iron-localstorage is a wrapper around window.localStorage (a cookie-like key-value storage). Also, the answer doesnt mention at all how it would help OP's question, but I think it was getting at this: one can use iron-localstorage almost like a global object; every component that wants to access this global can have an iron-localstorage, and they will all share that data. – Verdagon Feb 16 '17 at 04:34
0

You can use <iron-meta> as described here:

<iron-meta key="info" value="foo/bar"></iron-meta>
...
meta.byKey('info').getAttribute('value').

or

document.createElement('iron-meta').byKey('info').getAttribute('value');

or

<template>
  ...
  <iron-meta id="meta"></iron-meta>
  ...
  this.$.meta.byKey('info').getAttribute('value');
  ....
</template>
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
  • if I'm not wrong, it's a kind of mechanism to specify key/value pairs which can be accessed from anywhere in the page? – Janos Jul 25 '15 at 15:44