Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout loses binding to internal observables when parent object is set to null

This is something I ran across today and was wondering if it's something I am doing wrong or perhaps a bug in Knockout.

Imagine there's 3 different view model states coming from a server:

State 1 = { AnObject: { WithString: "SomeText" } }
State 2 = { AnObject: null }
State 3 = { AnObject: { WithString: "DifferentText" } }

If I do this:

<p data-bind="text: AnObject.WithString"></p>

Assuming appropriate Knockout binding, I would expect the text of that element to be "SomeText", then nothing, then "DifferentText" as a update my KO view model through all three states.

What actually happens is the first state works fine (text becomes "SomeText"), then on the second state the text does not change and it seems that the binding is lost altogether because on the third state the text still doesn't change even though there's now a good value to use.

Here's a JSFiddle demonstrating the issue:

http://jsfiddle.net/zAuDs/4/

like image 222
JPRO Avatar asked Dec 04 '25 14:12

JPRO


1 Answers

I believe that this is an artifact of how the mapping plugin handles updates.

On the first mapping an observable is created for InternalThing.

On the second mapping the whole observable is removed from the view model (UI is still bound to it).

On the third mapping a new observable is created for InternalThing, which is not bound to the UI.

One option would be to force Obj to be observable and use a with: Obj around your element.

  var ViewModel = function(data) {
      var me = this;
      ko.mapping.fromJS(data, {}, me);
      me.Obj = ko.observable(me.Obj);   

      return me;
  };

Then, bind like:

<!-- ko with: Obj -->
<h1 data-bind="text: InternalThing">1</h1>
<!-- /ko -->

Sample: http://jsfiddle.net/rniemeyer/bJkKp/

like image 133
RP Niemeyer Avatar answered Dec 08 '25 15:12

RP Niemeyer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!