Reputation: 2419
I'm looking for knockout if or visible best practices in this case:
<div data-bind="visible: $root.obsVar()">
...
<input type="text" data-bind="value: $root.obsVar().someField" />
...
</div>
In case when $root.obsVar()
is undefined, error will be thrown. If you change visible
to if
, problem will miss, but it requires rewriting of the html. If there is a lot of murkup in div
, it takes a lot of time. Are there any reasons to change $root.obsVar().someField
to $root.getSomeFieldValue
that always returns correct value or undefined? Or maybe there are other techniques not to get overhead and avoid errors.
Upvotes: 15
Views: 8849
Reputation: 20091
You might find you need to use both.
Use if
to remove the markup from the DOM - preventing possible JS errors, and so it doesn't take up space on the page.
And then use visible
to hide the element until the page is fully loaded.
<!-- ko if: whatever -->
<div data-bind="visible: true" style="display: none">
my content
</div>
<!-- /ko -->
Upvotes: 2
Reputation: 39025
As stated in David Sherret's answer, the main difference is that with if
the DOM elements disappear if the condition is not fulfilled, and with visible
they're simply hidden, but are always present in the DOM tree.
The main consequence is that if you're using if
and you have to handle events you'll have to use delegated events, or attach them everytime the elements are recreated. When you use KO you usually don't do event handling, because you use bindings like click
which are handled by KO, and so you don't have this problem. But you can have some other frameworks involved, like validators, jQuery UI date pickers, and so on, which will have trouble to work correctly with KO's if
.
Upvotes: 1
Reputation: 106660
It really depends on the scenario. From the docs:
if
plays a similar role to thevisible
binding. The difference is that, withvisible
, the contained markup always remains in the DOM and always has itsdata-bind
attributes applied - thevisible
binding just uses CSS to toggle the container element’s visiblity. Theif
binding, however, physically adds or removes the contained markup in your DOM, and only applies bindings to descendants if the expression is true.
In your scenario, the only way to prevent an error without using if
, when someField
is null, is to do something along these lines:
data-bind="value: ($root.obsVar() == null) ? null : $root.obsVar().someField"
That's really annoying to have to write each time you access a property. It makes the code harder to maintain and it makes it easier to make a mistake—especially when you're adding a new binding to an obsVar
's property because you will have to remember to do that null check.
Unless you see some clear performance benefits from using visible
in your situation, my recommendation would be to go with if
because then you only have to write the check in one place and not multiple places.
Upvotes: 18
Reputation: 11
Try using $root.obsVar without the (). That should work for either if or visible. The difference between the two is that "visible" just hides the div, which will still exist in the DOM, but "if" leaves it out of the DOM.
Upvotes: 1