Search code examples
javascriptractivejs

Define a component used as list element


I have a component that I'd like to use as some kind of list element:

var ListElement = Ractive.extend({
    // the template defining the look of each list element 
    // is currently defined within a <script> block
    template: '#listElementTmpl';
});

Furthermore, I have some kind of parent maintaining the list and its elements:

var App = Ractive.extend({
    template: 'appTmpl',

    components: {
        ListElement: ListElement
    },

    data: {
        listElements: []
    },

    add: function(info) {
        var element = new ListElement({
            data: {
                info: info
            }
        });
        this.push('listElements', element);
    }
});

Finally, I would define the App's template as something like:

<div>
    {{#each listElements}}
        <ListElement />
    {{/each}}
</div>

The list elements are drawn as defined in their template, but, unfortunately, the data binding somehow somewhere got lost. Can anyone tell me, what I am missing?


Solution

  • You don't create the component elements, you simply modify the data and ractive will create the components for you.

    var ListElement = Ractive.extend({
        template: '#listElementTmpl'
    });
    
    var App = Ractive.extend({
        template: '#appTmpl',
    
        components: {
            ListElement: ListElement
        },
    
        add: function(info) {
            this.push('list', { info } );
    		this.set('newInfo');
        }
    });
    
    new App({ 
        el: document.body,
        data: { 
            list: [{
    	        info: 'some info from first item'
    	    }] 
        }
    });
    <script src="http://cdn.ractivejs.org/edge/ractive.min.js"></script>
    
    <script id='appTmpl' type='text/ractive'>
    	<ul>
    		{{#each list}}
    			<ListElement info='{{info}}'/>
    		{{/each}}
    	</ul>
    	<div>
    		<input value='{{newInfo}}'>
    		<button on-click='add(newInfo)'>add</button>
    	</div>
    </script>
    
    <script id='listElementTmpl' type='text/ractive'>
    	<li>{{info}}</li>
    </script>