MotoWilliams
MotoWilliams

Reputation: 1568

Empty array bound element disappears on page load

I have a simple collection bound to an observableArray that is initially empty. When the page renders it 'sometimes' will show the empty template before the binding kicks in and removes the element. If you can't see it refresh the page a few times. This is happening as below with the container less templates but also happens with normal inline and script tag style templates.

View:

<div>
  <input data-bind="value: address"/>
  <button data-bind="click: search">Search</button>
</div>
<!-- ko if: list().length > 0 -->
<h5 data-bind="text: list().length"></h5>
<!-- /ko -->
<!-- ko foreach: list -->
    <div class="result" data-bind="text: addr"></div>
<!-- /ko -->​

Javascript:

$(function() {

  var viewModel = function() {
      var self = this;

      self.address = ko.observable("Portland");

      self.list = ko.observableArray();
      self.hasData = function(){return self.list().length > 0;};

      self.search = function() {
              self.list.push({ addr: "Item01" , index: 1 });
              self.list.push({ addr: "Item02" , index: 2 });
              self.list.push({ addr: "Item03" , index: 3 });      
      };
  };

  var vm = new viewModel();
  ko.applyBindings(vm);
});​

I doesn't seem to happen to much on jsFiddle - http://jsfiddle.net/motowilliams/mx7SM/ or JSBin but does happen locally and when deployed - http://knockouttest.herokuapp.com/.

Any ideas?

Upvotes: 1

Views: 350

Answers (2)

Tom W Hall
Tom W Hall

Reputation: 5283

For me, the delay only occurs with the presence of those 2 github gist scripts - which presumably won't be a problem in production? Your binding doesn't occur until the document is ready and they seem to be markedly slowing it down.

Upvotes: 0

RP Niemeyer
RP Niemeyer

Reputation: 114792

I am not able to see the issue in your sample, but a couple choices that you have are:

  • use a named template in a script tag. Browsers won't render markup that is in the script tag. You did seem to indicate that you tried it, but you might want to give it another look.

  • otherwise, you can wrap it in an element and set display: none on it and use data-bind="visible: true" as well. When the page loads it will be hidden and KO will set it to visible when the binding is happening. Something like:

Here is a sample with the original and the two options that I mentioned and a two second delay in applying the bindings: http://jsfiddle.net/rniemeyer/mx7SM/2/

Upvotes: 1

Related Questions