Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load knockout components dynamically

Tags:

knockout.js

This is my html :

<a href="#page1">page 1</a>
<a href="#page2">page 2</a>

This is my js :

define(['jquery', 'knockout'], function ($, ko) {


     ko.components.register('page1', {
    require: 'App/Controllers/page1'
});
ko.components.register('page2', {
    require: 'App/Controllers/page2'
});

    window.onhashchange = function () {
        var hash = location.hash.replace('#', '');
        $('#body').html('<' + hash + '></' + hash + '>'); //hash = page1 or page2
    }

    ko.applyBindings();
})

However, when hash changes, components doesn't load and body content is simply: <page1></page1> or second page. If i would change my js like this :

define(['jquery', 'knockout'], function ($, ko) {

    ko.components.register('page1', {
    require: 'App/Controllers/page1'
});
ko.components.register('page2', {
    require: 'App/Controllers/page2'
});

    $('#body').html('<page1></page1>');

    ko.applyBindings();
})

It works fine

like image 462
Nika Javakhishvili Avatar asked Nov 11 '15 14:11

Nika Javakhishvili


1 Answers

Replacing the body html is going to leave everything unbound. You should not use cleanNode; it is a kludge.

If you want to change which component is being used, use the component binding on the containing tag (body is fine), using an observable that contains the desired component. Here's an example, using a timer to change the template.

ko.components.register('page1', {
    template:'page1 template'
});
ko.components.register('page2', {
    template:'page2 template'
});
 
vm = {page:ko.observable('page1')};
ko.applyBindings(vm);

setTimeout(function () {
    vm.page('page2');
}, 1500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="component: page"></div>
like image 106
Roy J Avatar answered Oct 12 '22 19:10

Roy J