2017-08-16 62 views
0

我们正在构建聚合物应用程序。 我们有一个元素阵列,它们在使用dom-repeat的组件中显示。下面是一个例子片段: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正确使用我的依赖关系...)。

到目前为止,我已经尝试过寻找到

  • 听众
  • notifyPath
  • 观察家

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

我知道使用像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> 

谢谢,

回答

1

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

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

儿童部件即another-component在烧成某一事件变化名':

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(我没有发现其他办法)。我希望这有帮助。

+0

嘿,我昨天晚上开始玩事件,我觉得这可能是真的。然而,在我的例子中,我不喜欢的是数据在数组级别上发生了变化(您将数据发送出去了,我会发现它更加干净,以便直接在项目中更改引用,并通过通知。你认为这是可能的吗? – jlengrand

+0

感谢plunkr,顺便说一句,我认为应该可以在元素级别更改数据的原因是因为我们使用对象的引用,所以我期望以某种方式能够影响项目。notifyPath可以做得更高,没有问题 – jlengrand

+1

好吧,我修改了你的例子,让它按照我的意愿工作。你可以在这里看到结果:http://plnkr.co/edit/4OKtToJ3J2eBJrk50PXu?p=preview 。谢谢你的帮助!顺便说一句,值得注意的是,你也可以直接在人员级别通知 – jlengrand

1

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

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

+0

嘿谢谢你的答案。我已经修复了使用字符串的方法。我在原始代码中使用了它们,但在构建此示例时忘记了它们。我也试图通知元素,但没有成功。 – jlengrand

+0

谢谢雅各布。昨天晚上几次阅读你的评论后,我开始明白你的意思。但只有在Ofisora提到notifyPath的时候,我才能让它工作 – jlengrand

相关问题