在Polymer元素之间共享数据更改

时间:2018-04-06 09:48:25

标签: javascript polymer

我有一个页面,我希望在同一组数据中包含三个单独的视图(一个显示所有数据和一个显示不同的摘要)。

我正在寻找一种方法将每个视图表示为Polymer元素,并在数据发生变化时更新每个视图。这些更改将是存储在数组中的对象的属性值。它是组件之间共享的数组。

我找到了一种方法,可以在数据发生变化时触发事件,在组件外部监听,然后调用notifyPath - 但它有点笨拙且可能更多因此,当我将代码的当前状态(一个带有两个Polymer元素的简单演示,其中一个是readonly)扩展到最终目标时(三个元素,所有这些元素都可以读取和写入数据)。

是否有更简单的方法来共享组件之间的更改?

的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>

示例-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>

示例-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>

1 个答案:

答案 0 :(得分:6)

以上代码可能与Polymer方式相似。没有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>

示例 - two.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 [];
                        }
                    }
                };
            }
        }
        window.customElements.define(ExampleTwo.is, ExampleTwo);
</script>
</dom-module>