Shibbir Ahmed
Shibbir Ahmed

Reputation: 1350

How to negate the if binding?

I am trying to achieve something like an "ifnot" binding, something like this:

<div data-bind="ifnot: Categories"><p>No Categories available</p></div>

<div data-bind="template: { name: 'category-template', foreach: Categories }"></div>

<script type="text/html" id="category-template">
     <p data-bind="text: Title"></p>
</script>

<script>
     var self;

     function viewModel() {
          self = this;
          self.Categories = ko.observableArray([]);
     }

     ko.applyBindings(new viewModel());

     var renderCategoryTemplate = function(data) {
          for (var i = 0; i < data.length; i++) {
               self.Categories.push({
                    Title: data[i].Title
               });
          }
     };
</script>

Is this possible? Or is there a better way to do this?

I can see the text "No Categories available" only for a second. But then it disappears. Any suggestions?

Upvotes: 0

Views: 196

Answers (3)

Shibbir Ahmed
Shibbir Ahmed

Reputation: 1350

If I change the outer div to p tag than every answers works:

<p data-bind="ifnot: Categories">
    <p data-bind="text: 'No Categories available'"></p>
</p>

also works:

<p data-bind="if: !Categories()">
    <p data-bind="text: 'No Categories available'"></p>
</p>

Not sure why

Upvotes: 0

PW Kad
PW Kad

Reputation: 14995

Just make it if not equal to

<div data-bind="if: !Categories()"><p>No Categories available</p></div>

This will evaluate to if there are no categories, then show this.

Edit If you don't want it to flicker do this -

<div data-bind="text: !Categories() ? 'There are no categories' : ''"></div>

Upvotes: 1

Ben McCormick
Ben McCormick

Reputation: 25728

Is there an ifnot binding

Yes there is an ifnot binding

http://knockoutjs.com/documentation/ifnot-binding.html

From those docs:

<div data-bind="ifnot: someProperty">...</div>

is equivalent to the following:

<div data-bind="if: !someProperty()">...</div>

assuming that someProperty is observable and hence you need to invoke it as a function to obtain the current value.

Why does it flicker?

The flickering you're seeing is because the dom renders first with that text before you run the knockout script and remove it. To eliminate that you can set the text using knockout

<div data-bind="ifnot: Categories">
    <p data-bind:"text:'No Categories available'"></p>
</div>

That way the text won't be displayed before knockout runs, since KO is required to process it. You can also now pull the message out and make it variable if desired.

Upvotes: 2

Related Questions