Ali Habibzadeh
Ali Habibzadeh

Reputation: 11558

How to prevent complete template rerender

I using this method on my view model to switch between the normal template and the editable template of table rows:

contactsViewModel.templateToUse = function (contact) {
         return contactsViewModel.selectedItem() === contact ? 'contacts-editTmpl' : 'contacts-itemsTmpl';
};

so instead of template name I call this method:

<tbody data-bind="template: { name: templateToUse, foreach: filterItems }"></tbody>

It works but I have serious concerns over it rendering a whole list again everytime I hit edit:

contactsViewModel.edit = function (contact) {
       contactsViewModel.selectedItem(contact);
};

I would like it to only change the template for the selectedItem and not the rest, but not sure how to go about it.

Thanks for helping

Upvotes: 0

Views: 155

Answers (1)

RP Niemeyer
RP Niemeyer

Reputation: 114792

One option is to just use foreach on your filteredItems and then use the template binding on each row with row-level templates.

Something like:

<tbody data-bind="foreach: items">
    <tr data-bind="template: { name: $root.templateToUse }"></tr>
</tbody>

view model like:

var ViewModel = function() {
    this.items = ko.observableArray([
        { name: ko.observable("one") },
        { name: ko.observable("two") },
        { name: ko.observable("three") }
    ]);

    this.selectedItem = ko.observable();

    this.templateToUse = function(item) {
        return item === this.selectedItem() ? "edit" : "view";   
    }.bind(this);
};

ko.applyBindings(new ViewModel());​

Sample: http://jsfiddle.net/rniemeyer/3rvTA/

Another option would be to move the "selected" observable to the item's themselves. This would work well if you wanted to be able to put multiple rows into edit mode.

Upvotes: 1

Related Questions