将数组传递给 Ractive js 组件

Passing arrays to Ractive js components

在 Ractive.js 中,如何将属性附加到传递到组件的数组中的每个对象,而不使它们对父 Ractive 对象可用?

一个组件可能想要添加额外的属性来帮助它管理它自己的内部状态。这是一个用作选项卡控件的示例组件。

组件 JS

var tabComponent = Ractive.extend({
isolated: true,
template: '#tabTemplate',
data: function(){
    return {
        items: [] // contains objects in this format { text: "title", detail: "detail" }
    };
},
onrender: function() {
    // add the extra property the component needs to be able to work
    for(var i = 0; i < this.get('items').length; i++){
        this.set('items[' + i + '].selected', false);
    }

    this.on('toggle', function(event){
        var keypath = event.keypath + '.selected';

        this.set(keypath, !this.get(keypath));
    });
}

});

组件模板

<ul>
    {{#items}}
    <li>
        <header class="tabHeader" on-click="toggle">{{text}} - Click to toggle!</header>
        <div class={{selected ? '' : 'hidden'}}>{{detail}}</div>
    </li>
    {{/items}}
</ul>

父 Ractive 对象可以在其模板中使用这样的组件。

<tab-control items="{{myItems}}"></tab-control>

父 Ractive 对象现在可以看到这个额外的 属性 添加纯粹是为了组件内部工作。如果父 Ractive 对象想要为 ajax 调用序列化数据,这会很烦人,因为它现在必须从组件中了解 属性。有没有什么办法可以防止这些组件特定的数据属性在其外部变得可用?

我添加了一个 example here。当您将模型打印到控制台时 window 您可以在数组中的每个项目上看到 'selected' 属性。

对于这些更简单的用例,您可以使用另一个数组来跟踪选定状态:

<ul>
    {{#items:i}}
    <li>
        <header class="tabHeader" on-click="toggle('selected.' + i)">{{text}} - Click to toggle!</header>
        <div class={{selected[i] ? '' : 'hidden'}}>{{detail}}</div>
    </li>
    {{/items}}
</ul>

只需确保将数据添加到您的组件中:

var tabComponent = Ractive.extend({
    isolated: true,
    template: '#tabTemplate',
    data: function(){
        return {
            items: [],
            selected: []
        };
    }
});

example

否则,您可以为每个项目使用一个组件,然后为该项目获得一个相关的数据容器:

{{#items}}
    <li>
        <tab item='{{this}}'/>
    </li>
{{/items}}

这给了你更多的控制权和能力来做一些事情,比如计算属性:

var tabComponent = Ractive.extend({
    template: '#tab',
    isolated: true,
    data: {
        selected: false
    },
    computed: {
        upperDetail: '${item.detail}.toUpperCase()'
    }

});

参见 http://jsfiddle.net/th2fywny/6/