Preventing (or controlling) custom bindings from re-rendering element.

55 views
Skip to first unread message

Dmitry Nutels

unread,
Jul 3, 2014, 8:46:13 AM7/3/14
to knock...@googlegroups.com
Hi.

I am not sure I can explain it properly, but I have a custom binding:

<div data-bind="custom: 'some primitive string value'"></div>

It only has init function, and no update:

KO.bindingHandlers.custom= {
  init: invokeSomeMethodThatDoesStuff
};

The issue is - that custom binding, inside, uses a mapped (using knockout.mapping) ViewModel and retrieves all sorts of
values from it, listens to some etc. so, when something (I am not entireely positive what, as it is a complex data structure) 
changes (is updated on the ViewModel), the entire element is re-rendered which is undesirable in my case. 

The reason is that this code:

setDomNodeChildren: function (domNode, childNodes) {
    ko.utils.emptyDomNode(domNode);
    if (childNodes) {
        for (var i = 0, j = childNodes.length; i < j; i++)
            domNode.appendChild(childNodes[i]);
    }
}

and emptyDomNode naturally removes the entire element.

Had the structure been simpler, I'd probably debug it and find the accessed triggering observable (I am guessing there is one) 
and change its access to peek or something.

My question is - is there:

1. a way to preven custom binding from re-rendering components
2. a giudeline/rule of thumb on how one goes about debugging such a thing to find the offending observable/property/whatever?

Thank you.

Ian Yates

unread,
Jul 4, 2014, 8:59:17 AM7/4/14
to knock...@googlegroups.com
I've seen one suggestion elsewhere which was to create a computed inside of your function, do the work in it (since it will be evaluated immediately if you don't manually defer it) and then dispose of it on the next line.  Any implicit subscriptions created will disappear with the disposal.  I've not tried it, and it seems like a hack, and I may well be missing something.... but it's worth a try :)
Message has been deleted

Dmitry Nutels

unread,
Jul 8, 2014, 1:56:40 AM7/8/14
to knock...@googlegroups.com
Thank you.

This works very well (would work just as well without mapping plugin, of course):

var data;
var computed = ko.computed(function() {
    data = ko.mapping.toJS(observable);
});
computed.dispose();
Reply all
Reply to author
Forward
0 new messages