0

I try to use Knockout like WPF-MVVM.
In WPF there is an option to notify the VM on property change.
For example: if I have a textBox, I can use UpdateSourceTrigger=PropertyChanged for notify the VM every click.

<Grid DataContext="MyVM">
    <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</Grid>

In Knockout I have build this simple app:

VM:

function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");

this.fullName = ko.computed(function() {
    return this.firstName() + " " + this.lastName();    
}, this);


}

ko.applyBindings(new AppViewModel());

View:

<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

<p>Full name: <strong data-bind="text: fullName"></strong></p>

I'm trying without success, to update fullName on textBox input click (not onblur).

EDIT:

The code works fine. I just want that lastname will update while writing on the firstname/lastname textbox.

Now it's updated onblur, it's not updated while writing.

cheziHoyzer
  • 4,803
  • 12
  • 54
  • 81
  • 1
    I can see nothing wrong with the current code. I have put it into a fiddle: http://jsfiddle.net/infiniteloops/en6AR/ and it works as expected. Perhaps you can explain further the issue you are having. – Gary.S Dec 29 '13 at 11:15
  • The code works fine. I just want that lastname will update while writing on the firstname/lastname textbox. Now it's updated onblur, it's not updated while writing. – cheziHoyzer Dec 29 '13 at 11:28
  • I see, well that makes more sense. Added an answer describing how to do this – Gary.S Dec 29 '13 at 11:34

2 Answers2

3

In order to change the update mode of an input as you are suggesting there are some built-in ways in knockout to accomplish this.

See this for reference: http://knockoutjs.com/documentation/value-binding.html

Specifically the part about value updates.

In this case specifically you could use valueUpdate: 'afterkeydown' to update the binding.

All that will need to change in this instance is your bindings.

<p>First name: <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></p>
<p>Last name: <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></p>

<p>Full name: <strong data-bind="text: fullName"></strong></p>

<button data-bind="click: capitalizeLastName">Go caps</button>

Updated JSFiddle: http://jsfiddle.net/infiniteloops/en6AR/1/

Gary.S
  • 7,076
  • 1
  • 26
  • 36
1

Your code logically fine, your problem is in mis-use of this inside the capitalizeLastName function.

In your case this keyword refers to the object the function belongs to, or the window object if the function belongs to no object but not your View-Model object. That's why in most KnockoutJS examples we use var self=this; at the first line of View-Model definition to obtain a refrence to the View-Model object.

Updated working demo based on your code

Check the following SO questions for better undertanding:

  1. In knockout.js, why “this” is being assigned to “self”?
  2. this inside function

Update

In order to update your view while writing firstname/lastname textbox, you need just to add valueUpdate: 'afterkeydown' to your binding.

From KnockoutJS documentation:

valueUpdate

If your binding also includes a parameter called valueUpdate, this defines additional browser events KO should use to detect changes besides the change event. The following string values are the most commonly useful choices:

"afterkeydown" - updates your view model as soon as the user begins typing a character. This works by catching the browser’s keydown event and handling the event asynchronously.

Updated Demo

Community
  • 1
  • 1
ebram khalil
  • 8,252
  • 7
  • 42
  • 60
  • The computed function binds the `this` value in the computed by using the (`function`, `this binding`) method call. So `this` is bound correctly. – Gary.S Dec 29 '13 at 11:21
  • The code works fine. I just want that lastname will update while writing on the firstname/lastname textbox. Now it's updated onblur, it's not updated while writing. – cheziHoyzer Dec 29 '13 at 11:27
  • Thanks @Gary.S . I updated my answer to be pointed at `capitalizeLastName` function not the `computed` one – ebram khalil Dec 29 '13 at 11:29