Andrew
Andrew

Reputation: 20101

Get length of property after destroying element in KnockoutJS

In KnockoutJS you can have a property that is an array of objects. Eg.

self.items could be made up of items:

var item = function (data){
  //mapping here
}

You can then "destroy" one of those objects by calling something like:

self.items.destroy(item);

But then if I check/bind to the length of self.items, it is still the full length (including destroyed objects). Eg, this won't get updated properly after destroying stuff, and stays visible:

data-bind="visible: myData.items().length > 0"

How to get the length, minus the destroyed objects?

I suppose I could create a computed kojsLength method and add it to every object, that loops over the array and counts all items that don't have the _destroy property?

But is there a built in KOJS solution, or do I have to do this?

Edit, my solution:

For me, since I have no use for the _destroy property on the back end, directly substituting in the remove function for destroy works perfect.

Upvotes: 1

Views: 168

Answers (1)

Regis Portalez
Regis Portalez

Reputation: 4860

That is because destroyed elements are not actually removed from the underlying array. They are just marked as destroyed, as you can see by running the below snippet.

There is no built-in KO solution for that.

If you want to exclude them by computing length, you need a custom length function which discards them:

function viewModel(name) {
  this.name = name;
}

var array = ko.observableArray([new viewModel("a"), new viewModel("b")]);

console.log(array().length);
array.destroy(array()[0]);
console.log(array().length);
console.log(JSON.stringify(array()));

function lengthOfAlive(obs) {
  var before = obs().length;
  var res = before;
  for (var i = 0; i < before; ++i) {
    if (obs()[i]._destroy)
      res--;
  }
  return res;
}

console.log(lengthOfAlive(array));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Upvotes: 1

Related Questions