Is this a KnockoutJS bug or am I screwing something up...

62 views
Skip to first unread message

Mustafa Saeed Haji Ali

unread,
Feb 26, 2012, 1:20:15 AM2/26/12
to knock...@googlegroups.com
Hey there,

I had an issue with KnockoutJS and I needed some help. I tried posting on StackOverflow but that didn't answer my question. Essentially the problem was that my app's behavior changed depending on whether I applied a style binding. Here's the text of my SO question:

I've been working my way through the KnockoutJS documentation and tried to modify example 3 of the "Writeable computed observables" section in this page.


The example basically shows a textbox and displays a message if the user enters a non-numeric value to the textbox. I tried to modify the code so that the textbox has a pink background when the message appears.


The problem is when you enter a invalid value the textbox turns pink as expected but the value you entered is replaced with what was originally there. I have no idea why this behavior is occurring since everything worked fine before I added the style binding to get the pink background. Try removing the style binding and notice how the behavior changes when you enter an invalid value.


What's going on?


The code is below or try out this jsfiddle.
    <p>
      Enter a numeric value:
      <input data-bind="value: attemptedValue
                       ,style: {backgroundColor: lastInputWasValid() ?
                                                 'transparent' :
                                                 'pink' }"/>
    </p>
    <div data-bind="visible: !lastInputWasValid()">That's not a number!</div>

    function MyViewModel() {
      this.acceptedNumericValue = ko.observable(123);
      this.lastInputWasValid = ko.observable(true);

      this.attemptedValue = ko.computed({
          read: this.acceptedNumericValue,
          write: function (value) {
              if (isNaN(value))
                  this.lastInputWasValid(false);   
              else {
                  this.lastInputWasValid(true);
                  this.acceptedNumericValue(value); // Write to underlying storage
              }
          },
          owner: this
      });   
    }

    ko.applyBindings(new MyViewModel());
EDIT: Here's another fiddle with the style binding removed. Try appending the letter 'a' and taking focus out of the textbox. Notice how the letter 'a' stays there. Try that with the original fiddle textbox and notice how it is removed. The only change between the two fiddles is the presence of the style binding.

JohnEarles

unread,
Feb 26, 2012, 8:21:31 AM2/26/12
to KnockoutJS
It make sense to me.

In your example without the style, Knockout does not have to re-render
your input (only the error), so the value stays the same.
In your example with the style, Knockout does have to re-render your
input (to add the style), so BOTH bindings execute and it reads the
value - which is the last accepted value.

Here is a version that saves the attempted value into one of two
observables, and reads from the appropriate one based on
lastInputWasValid:


http://jsfiddle.net/jearles/VSWfr/
Reply all
Reply to author
Forward
0 new messages