Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

javascript - Sharing changes to data between Polymer elements

I have a page where I want to include three separate views (one showing all the data and ones with different summaries) on the same set of data.

I'm looking for a way to represent each view as a Polymer element and have each one update whenever the data changes. These changes will be to the values of properties of objects which are stored in an array. It is the array that is shared between the components.

I've found an approach that works by firing an event when there is a change to the data, listening for it outside the components, and then calling notifyPath — but it is somewhat unwieldy and likely to be more so as I grow my code its current state (a simple demo with two Polymer elements, one of which is readonly) to the end goal (three elements, all of which can read and write to the data).

Is there a simpler way to share changes between components than this?


index.html

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

    <head>
        <meta charset="utf-8">
        <title>polymer-test</title>
        <script>
            (function() {
                var data = [{
                    name: "Alice",
                    amount: 100
                }, {
                    name: "Bob",
                    amount: 200
                }];
                document.addEventListener('WebComponentsReady', function() {
                    document.querySelector('example-one').data = data;
                    document.querySelector('example-two').data = data;

                    document.querySelector('example-two').addEventListener('there-is-a-change', function(e) {
                        document.querySelector('example-one').notifyPath(e.detail.path);
                    })

                });
            })();
        </script>

        <script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
        <link rel="import" href="/src/polymer-test-app/example-one.html">
        <link rel="import" href="/src/polymer-test-app/example-two.html">
    </head>

    <body>
        <h1>One</h1>
        <example-one></example-one>
        <h1>Two</h1>
        <example-two></example-two>
    </body>

</html>

example-one.html

<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/polymer/lib/elements/dom-repeat.html">

<dom-module id="example-one">
    <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <table>
    <tbody>
        <template is="dom-repeat" items="{{data}}">
            <tr>
                <td>{{item.name}}</td>
                <td>{{item.amount}}</td>
            </tr>
        </template>
    </tbody>
    </table>
    </template>

    <script>
        class ExampleOne extends Polymer.Element {
            static get is() {
                return 'example-one';
            }
            static get properties() {
                return {
                    data: {
                        type: Array,
                        notify: true,
                        value() {
                            return [];
                        }
                    }
                };
            }
        }

        window.customElements.define(ExampleOne.is, ExampleOne);
    </script>
</dom-module>

example-two.html

<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/polymer/lib/elements/dom-repeat.html">

<dom-module id="example-two">
    <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <table>
    <tbody>
        <template is="dom-repeat" items="{{data}}">
            <tr>
                <td>{{item.name}}</td>
                <td><input value="{{item.amount::input}}"></td>
            </tr>
        </template>
    </tbody>
    </table>
    </template>

    <script>
        class ExampleTwo extends Polymer.Element {
            static get is() {
                return 'example-two';
            }
            static get properties() {
                return {
                    data: {
                        type: Array,
                        notify: true,
                        value() {
                            return [];
                        }
                    }
                };
            }
            static get observers() {
                return [
                    'arrayChanged(data.*)'
                ]
            }
            arrayChanged(data) {
                console.log("Changed!");
                this.dispatchEvent(new CustomEvent("there-is-a-change", {
                    detail: {
                        path: data.path
                    }
                }));
            }

        }

        window.customElements.define(ExampleTwo.is, ExampleTwo);
    </script>
</dom-module>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Above codes may like this with Polymer way. without notifyPath.

DEMO

index html:

<html>

 <body> 

<dom-module id="my-test">
<template>
<style>
    :host {
      display: block;
      text-align: center;
    }
</style>
  <body>
    <h1>One</h1>
    <example-one data={{data}}></example-one>
    <h1>Two</h1>
    <example-two data={{data}}></example-two>
  </body>


</template> 
</dom-module>



<my-test></my-test>

</body>
</html>

example-one.html:

<dom-module id="example-one">
    <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <table>
    <tbody>
        <template is="dom-repeat" items="{{data}}">
            <tr>
                <td>{{item.name}}</td>
                <td>{{item.amount}}</td>
            </tr>
        </template>
    </tbody>
    </table>
    </template>
    <script>
 class ExampleOne extends Polymer.Element {
            static get is() { return 'example-one'; }
            static get properties() {
                return {
                    data: {
                        type: Array,
                        notify: true,
                        value() {
                            return [{ name: "Alice",
                                      amount: 100
                                      }, {
                                      name: "Bob",
                                      amount: 200          }];
                        }
                    }
                };
            }
        }

        window.customElements.define(ExampleOne.is, ExampleOne);
   </script>
</dom-module>

And example-two.html is:

<dom-module id="example-two">
    <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <table>
    <tbody>
        <template is="dom-repeat" items="{{data}}">
            <tr>
                <td>{{item.name}}</td>
                <td><input value="{{item.amount::input}}"></td>
            </tr>
        </template>
    </tbody>
    </table>
    </template>
<script>
class ExampleTwo extends Polymer.Element {
            static get is() {
                return 'example-two';
            }
            static get properties() {
                return {
                    data: {
                        type: Array,
                        notify: true,
                        value() {
                            return [];
                        }
                    }
                };
            }
        }
        window.customElements.define(ExampleTwo.is, ExampleTwo);
</script>
</dom-module>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...