Ractivejs:如何从动态添加的组件中收集值?

Ractivejs: how to collect values from dynamically added components?

参考:this jsbin

我的组件有一个 select 框:

var ListItem = Ractive.extend({
  template:`<select value='{{color}}'>
            <option disabled selected value=null>select color</option>
            <option value='red'>red</option>
            <option value='green'>green</option>
            <option value='blue'>blue</option>
            </select>`
})

并且主应用可以通过点击'Add'动态添加组件:

var ractive = new Ractive({
  el:'#container',
  template:`<p on-click='@this.add_comp()'>Add</p>
            <p>{{colors}}</p>
            {{#list}}
            <listItem />
            {{/list}}`,
  data:{ list: []},
  computed:{
    colors(){
      var items = this.findAllComponents('listItem')
      cols=[]
      for(var i=0; i<items.length; i++){
        cols[i] = items[i].get('color')
      }
      return cols
    }
  },
  components:{ listItem: ListItem },
  add_comp(){ this.push('list',{})}
})

我需要将组件的 select 框的值作为数组收集到父级中,例如['red','green','blue'] 但是当添加组件和颜色 selected 时,数组不会更新。

如果您能提供任何见解,我们将不胜感激。提前致谢。

AFAIK,Ractive 依赖项基于数据键路径,所以我猜测为什么调用 this.findAllComponents('listItem') 不会为其添加依赖项。我尝试添加对 this.get('list') 的调用,但这使得在添加新组件之前调用计算得到。我知道你可以 defer 观察者直到模板渲染发生,所以你可能需要使用 oberserver 而不是计算。

您应该 "encapsulate" 您的组件使用它们自己的数据。来自组件外部的值作为参数传递给组件,并且当数据被绑定时,您将始终使用您的 "parent" 数据,而不是组件内部的数据。

所以这是组件:

var ListItem = Ractive.extend({
  data: { color: "" },
  template:`<select value='{{color}}'>
            <option value=null>select color</option>
            <option value='red'>red</option>
            <option value='green'>green</option>
            <option value='blue'>blue</option>
            </select>`
})

如您所见,它有自己的数据块...

现在我们 "inject" 来自父级的数据:

var ractive = new Ractive({
  el:'#container',
  template:`<p on-click='@this.add_comp()'>Add</p>
            <p>{{colors}}</p>
            {{#list}}
            <listItem color="{{this.color}}" />
            {{/list}}`,
  data:{ list: []},
  computed:{
    colors(){
      var items = this.get('list');
      cols=[]
      for(var i=0; i<items.length; i++){
        cols[i] = items[i].color;
      }
      return cols
    }
  },
  components:{ listItem: ListItem },
  add_comp(){ this.push('list',{ color: "" })}
})

正如您在 "parent" 组件中看到的,我们将本地值传递给绑定的 "child" 组件。一旦我们更改子组件的颜色 属性,"parent" 组件中的列表 属性 将更新。

另一个重要的部分是 computed colors() 属性 包含一个在内部使用 this.get('list') 列出 属性 的依赖项。

我希望这能回答你的问题。

此致, 安迪