1

I can write a knockoutjs data binding expression in two different ways:

1. <div data-bind="text: FirstName"></div>
2. <div data-bind="text: FistName()"></div>

Note the two parens after FirstName in the second example. They both seem to work. Is there a difference?

2 Answers2

2

There is a difference.

They will only work both if FirstName is a ko.observable. If it is a plain value, only the first variant will work.

An observable does not hold its value directly. It is a function that provides access to the value. Therefore it must be called to get the value (i.e., strictly correct is text: FistName()).

But knockout is helpful and anticipates that. Therefore it will call the observable for you if you did not do it yourself.

Responsible for this is the helper function ko.utils.unwrapObservable(), which takes a parameter, determines whether it is an observable or a plain value and returns its value in both cases.

Knockout uses this function on every binding you define, so it does not matter if you call the observable yourself (text: FistName()) or let knockout do it behind the scenes (text: FirstName).


Quirk:

Knockout parses the binding expression <binding>: <expr> and determines whether <expr> is a simple identifier or something more complex.

Whenever <expr> is a simple identifier—like FirstName—knockout will apply unwrapObservable() automatically, because the situation is unambiguous.

But whenever <expr> is more complex—like 'Dear ' + FirstName—knockout constructs a custom function from the expression. Now things become ambiguous and you are required to call the observable yourself, like this: 'Dear ' + FirstName().

Compare: http://jsfiddle.net/Tomalak/cU4qw/

Tomalak
  • 332,285
  • 67
  • 532
  • 628
1

I would recommend you to read the following article: [10 Things to Know About KnockoutJS]

Quote from the article:

Most bindings will call ko.utils.unwrapObservable on the value passed to it, which will safely return the value for both observables and non-observables. However, in a binding if you use an observable in an expression, then you need to reference it as a function. Likewise, in code you typically need to reference your observables as functions, unless you actually want to pass the observable itself (not the value).

<div data-bind="visible: someFlag">...</div>
<div data-bind="visible: !someFlag()">...</div>
Artem Vyshniakov
  • 16,355
  • 3
  • 43
  • 47