Search code examples
ractivejs

Change components with ajax. (Ractivejs)


views.list = Ractive.extend({/*...*/});

var Content = Ractive.extend({
    template: '#template-content',
    components: {
        //view: views['list']
    },
    onrender: function() {
        /* call this.request */
    },
    request: function(route) {
        var self = this;
        $.ajax({
            url: route,
            type: 'GET',
            data: {},
            dataType: 'json',
            success: function(data){
                self.components.view = views[data.view];
            }
        });
    }
});

Ajax request returns {view:'list'}. I write in the console: "Content.components.view" and see:

function ( options ) {
    initialise( this, options );
}

But "Content.findComponent('view')" returns "null".

It will work if I uncomment the line "//view: views['list']" in the components. How to dynamically change the component?

Update 1:

I thought I can do this:

var Content = Ractive.extend({
    components: {
        // Aaaand add listener for data.view?
        view: function(data) {
            return views[data.view];
            // But no, it is not updated when changes data.view ...
        }
    },
    data: {},
    oninit: function() {
        var self = this;
        self.set('view', 'list');
    },
});

Not work.. Why then need "data" argument?


Solution

  • I won :)

    // Create component globally
    Ractive.components.ListView = Ractive.extend({});
    
    // Create ractive instance
    var Content = Ractive.extend({
        template: '#template-content',
        partials: {
            view: 'Loading...' // So... default
        },
        oninit: function() {
            var self = this;
            $.ajax({
                ...
                success: function(data){
                    // Hardcore inject component
                    self.partials.view = '<'+data.view+'/>';
    
                    // Little hack for update partial in template
                    self.set('toggle', true);
                    self.set('toggle', false);
                }
            });
        },
    });
    

    In Content template:

    {{^toggle}}{{>view}}{{/}}
    

    It's works-fireworks!