【问题标题】:Passing arrays to Ractive js components将数组传递给 Ractive js 组件
【发布时间】:2026-01-30 10:50:01
【问题描述】:

在 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。当您将模型打印到控制台窗口时,您可以在数组中的每个项目上看到“选定”属性。

【问题讨论】:

    标签: ractivejs


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回复!这很有意义:) 出于兴趣(在我将您的答案标记为正确之前)如果组件更复杂怎么办?将其分解成更小更简单的组件是解决方案吗?
    • > 将其分解为更小的更简单的组件是解决方案吗?确切地说,已编辑答案并带有该策略的示例。
    • 太好了!感谢您的帮助:)