dom 中的项目更改 - 重复未传达给其他项目

Item changing in dom-repeat not communicated to other items

我们正在构建聚合物应用程序。 我们有一个 元素数组 ,它们在使用 dom-repeat 的组件中显示。这是一个示例片段:

//main component
<h2>List of elements</h2>
<template is="dom-repeat" items="{{elements}}" as="item" indexAs="index">
    <another-component element="{{item}}" ident$="{{index}}"></another-component>
</template>

//sub component
<h3>{{element.name}}</h3>
<h4>{{element.person.name}}</h4>
<paper-button on-tap="_changeName">Change name!</paper-button>

数组的对象有一些共同的引用。你可以这样看他们:

//main component
<script>
    var fred = {"name": "fred"};
    var tom = {"name": "tom"};

    Polymer({
        is: 'example-component',
        properties: {
            elements: {
                type: Array,
                value: [{"name": "Main1", "person": fred}, {"name": "Main2", "person": tom}, {"name": "Main3", "person": fred}],
                notify: true
            }
        }
    });
</script> 

现在,我希望能够在我的项目中更改嵌套元素。

在本例中,我希望更改项目 3 的人员值。

但是由于项目 3 的人物参考与项目 1 相同,我也希望人物 1 发生变化。

但是,我遇到的是项目 1 没有更新。

There is a complete example setup at this address.(我可以让 jsfiddle 正确处理我的依赖项...)。

到目前为止,我已经尝试调查

没有成功。 我也想避免将我的整个数组传递给我的项目。

我知道使用像 Redux 这样的状态对象可以很容易地解决这个问题,所以不幸的是这不是这里的解决方案。

我在互联网上找到了很多关于如何让数据冒泡但又不像我现在尝试做的那样冒泡的资源。

如有任何帮助,我们将不胜感激。


完整代码供参考:

主要成分

<link rel="import" href="/polymer/polymer.html">
<link rel="import" href="/components/another-component/another-component.html">

<dom-module id="example-component">
    <template>
        <style>
            :host {
                display: block;
            }
        </style>

        <h1>Example</h1>

        <h2>List of elements</h2>
        <template is="dom-repeat" items="{{elements}}" as="item" indexAs="index">
            <another-component element="{{item}}" ident$="{{index}}"></another-component>
        </template>

    </template>
    <script>
        var fred = {"name": "fred"};
        var tom = {"name": "tom"};

        Polymer({
            is: 'example-component',
            properties: {
                elements: {
                    type: Array,
                    value: [{"name": "Main1", "person": fred}, {"name": "Main2", "person": tom}, {"name": "Main3", "person": fred}],
                    notify: true
                }
            }
        });
    </script>
</dom-module>

子组件

<dom-module id="another-component">
    <template>
        <style>
            :host {
                display: block;
            }
        </style>

        <h3>{{element.name}}</h3>
        <h4>{{element.person.name}}</h4>
        <paper-button on-tap="_changeName">Change name!</paper-button>

    </template>
    <script>
        Polymer({
            is: 'another-component',
            properties: {
                element: {
                    type: Object,
                    notify: true
                }
            },

            _changeName: function(){
                this.set('element.person', {"name": "bobby"});
                this.notifyPath('elements');
                this.notifyPath('element');
                this.notifyPath('element.person');

            }
        });
    </script>
</dom-module>

谢谢,

您可能希望让实际进行更改的元素触发一个事件,说明它更改了值。然后让父元素监听它,当它收到一个更改的事件时,它可以执行 this.notifyPath('elements'); 调用。

在对 notifyPath 的调用中,您传递的是对象,但它应该是字符串路径而不是对象。

子组件未更改父组件的值。正如 Jacob Miles 所建议的那样,您需要触发一个事件来更改值。然后从父元素监听,可以通知整个元素数组的变化。

这里是 plnkr link : http://plnkr.co/edit/tuqKh4ANUTspa05GZ9mi?p=preview

子组件即 another-component 正在触发一个事件 'change-name':

this.fire('change-name', {"newPersonName" : "bobby","index":this.i });.

父组件,即 example-component 正在侦听该事件并通知更改:

this.addEventListener('change-name', function (e) {
     this.elements[e.detail.index].person.name = e.detail.newPersonName;

     for(var i =0; i< this.elements.length; i++){
             this.notifyPath('elements.'+i+'.person.name'); 
     }

 });

为了通知我们需要使用更改的确切路径,所以我将 notifyPath 保持在循环中(我没有找到其他方法)。希望对您有所帮助。