When do I call an observable as a function?

198 views
Skip to first unread message

LeArgus

unread,
Apr 18, 2021, 8:04:22 PM4/18/21
to KnockoutJS
I am having difficulty following this example from the official documentation for the hasFocus binding

View:

<p> 
  Name: <b data-bind="visible: !editing(), text: name, click: edit">&nbsp;</b>
  <input data-bind="visible: editing, value: name, hasFocus: editing" /> </p> 
<p><em>Click the name to edit it; click elsewhere to apply changes.</em></p> 

ViewModel:
function PersonViewModel(name) { // Data 
  this.name = ko.observable(name); 
  this.editing = ko.observable(false); // Behaviors 
  this.edit = function() { this.editing(true) } 
}
ko.applyBindings(new PersonViewModel("Bert Bertington"));

My confusion comes from the "editing" observable which has not been declared as a function but is being called in the view like a function with !editing() and not like a function with visible: editing and hasFocus: editing.

I have read the documentation from knockoutjs.com but can't figure out what the rules are for referencing observables from the view. If I have an observable value xyz123 when do I reference it in the view as foo() and when do I reference it as foo?

Jonathan Shay

unread,
Apr 18, 2021, 8:32:40 PM4/18/21
to knock...@googlegroups.com
Typically you can refer to just the property (without the "()") if it's a simple reference. If you're instead building some kind of comparison in the view binding, then you'd use the parenthesis. As far as the "!editing()" binding, that should work the same if it were just "!editing" (without the parenthesis).

Message has been deleted
Message has been deleted

LeArgus

unread,
Apr 18, 2021, 9:08:09 PM4/18/21
to KnockoutJS
Thanks for the reply. 

It does seem like I should be able to leave out the parenthesis and just call !editing, but that doesn't work.
js.jpg2.jpg

LeArgus

unread,
Apr 18, 2021, 9:17:33 PM4/18/21
to KnockoutJS
I posted this question in SO if you'd like to copy the code and try for yourself. I wasn't allowed to upload the files here.

Jonathan Shay

unread,
Apr 19, 2021, 6:43:13 AM4/19/21
to knock...@googlegroups.com
Actually, now that I've slept on it, it's the use of the negating operator that changes this from a

Jonathan Shay

unread,
Apr 19, 2021, 6:44:43 AM4/19/21
to knock...@googlegroups.com
Oops. It's the use of the negating operator that changes the binding from a simple reference to an operation. That's why the parenthesis are required. Sleep does wonders for the mind.

Michael Bray

unread,
Oct 9, 2021, 12:43:15 PM10/9/21
to KnockoutJS
That's not quite true about the use of negation...  when using ! you should always use the ()'s on observables.  If you use ! without the parentheses, it will apply as a ! to the *observable function* not the value of the observable.  To see this in action, see this example:  https://jsfiddle.net/flmbray/n268sgkm/.  If the ()'s were not needed when using ! then you would expect both the A's and B's to follow the same pattern (true / false / false for A, then false / true / true for B).  For the A's you do see that a is true and !a is false, but this is misleading.  Look at the B's - b is false, but !b is also false!  Only !b() works correctly.  The !b is like saying !(function(){...}).  It's the same for a - !a is like saying !(function(){...}).  Because of the loose interpretation of javascript of what ! does, it sees "something" (the observable function) and then negates it, resulting in false for both !a and !b.  However !a() and !b() forces the observables to evaluate, then negates the values, as is expected.  Bottom line - always use the parentheses when using ! or any expression of an observable (a && b).  Better yet, always use parentheses when you are referring to ANY observable - it will help improve the clarity of the code because even though it's not strictly needed, it makes it clear that the variable is an observable (IMO).
Reply all
Reply to author
Forward
0 new messages