Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a visible parameter to an 'or' statement in Knockout

I would like to bind a visible property to be true when one of two conditions are true. Something like the following

 <tr data-bind="visible: active || $parent.displayDeactive">....</tr>

My code works when I do one or the other bindings but not when I put the || in there. I haven't found any documentation that says I can put any logic in this binding, but if I can't do it directly what is the est way to do it since I am binding a property of a template and one object of the $parent viewmodel.

like image 950
PlTaylor Avatar asked Jan 10 '12 12:01

PlTaylor


People also ask

What is binding in Knockout?

Advertisements. This binding is used to bind the child elements of an object in the specified object's context. This binding can also be nested with other type of bindings such as if and foreach.

How do I set observable value in Knockout?

To create an observable, assign the ko. observable function to the variable. A default value can be specified in the constructor of the call. Knockout then converts your variable into a function and tracks when the value changes, in order to notify the UI elements associated with the variable.

What is two-way binding in knockout JS?

KO is able to create a two-way binding if you use value to link a form element to an Observable property, so that the changes between them are exchanged among them. If you refer a simple property on ViewModel, KO will set the form element's initial state to property value.


2 Answers

If you are using the value of an observable in an expression then you need to reference them as a function. So, if active and displayDeactive are observables you would do:

data-bind="visible: active() || $parent.displayDeactive()"

There are a few ways to move it to the view model, you could:

  • create a computed observable on the child (function would need to be able to reference the parent)
  • create a function on the parent that takes in the child and returns your value (bindings are executed in a computed observable, so it will fire again when any observable that it accesses changes)
  • create a function on the child that takes in the parent and returns the value (same note as above)

Sample of logic in the binding and using a function on the parent here: http://jsfiddle.net/rniemeyer/f6ZgH/

like image 169
RP Niemeyer Avatar answered Oct 03 '22 14:10

RP Niemeyer


Add the parens after the observables, since you are evaluating them.

<input type="checkbox" data-bind="checked:displayDeactive"> Display deactive</input>
<br/><br/>
<table>
    <tbody data-bind="foreach: products">
        <tr data-bind="visible: active() || $parent.displayDeactive()">
            <td><span data-bind="text:name"></span></td>
        </tr>
    </tbody>
</table>

You can find the full code here: http://jsfiddle.net/johnpapa/gsnUs/

You could use a computed property on the templated item that evaluates the expression (just saw the @RPNiemeyer responded with that too ... I +1'd).

like image 31
John Papa Avatar answered Oct 03 '22 12:10

John Papa