0

I built an app in early version of knockout and the code looked like:

    var ProductCollection = function(products, metadata) {
        var self = this;
        this.allProducts = products;
        this.activeProducts = ko.observableArray(products);

Then if I filtered out items from the activeProduct array like:

    this.activeProducts.remove(function(item) { //some code })

I was able to reset activeProducts to all products by doing something like:

    this.activeProducts(this.allProducts);

But now it seems like if I do the remove function above its removing products from this.allProducts also... Is the products i'm passing in and setting linking to the same reference or something? I don't get why this would happen now and not before. I'd like to be able to keep this.activeProducts and this.allProducts as separate arrays.

Jim G.
  • 15,141
  • 22
  • 103
  • 166
michael
  • 396
  • 5
  • 16
  • 2
    `products` is the same array in both cases. You will want `activeProducts` to either be a copy of the array (`products.slice(0)` is a quick way to do that) or you can use a `computed` observable to represent the filtered version of your products. – RP Niemeyer Oct 24 '12 at 19:51

1 Answers1

2

As your experimentation has shown, ko.observableArray() simply wraps the underlying array. It doesn't clone the underlying array and then make a new instance.

Here's more from the the Knockout documentation:

An observableArray tracks which objects are in the array...

An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed...

...You can get the underlying JavaScript array by invoking the observableArray as a function with no parameters...

Technically you can use any of the native JavaScript array functions to operate on that underlying array...


// Thanks @RP Niemeyer
this.activeProducts = ko.observableArray(products.slice(0));

// Deep copy with jQuery
this.activeProducts = ko.observableArray(jQuery.extend(true, {}, products));

Also, if you're really curious, there's an entire question dedicated to Javascript cloning over here.

Community
  • 1
  • 1
Jim G.
  • 15,141
  • 22
  • 103
  • 166
  • Thanks for the reply. Do you happen to know if older versions Knockout actually cloned the data for you? It use to work as if I had done the cloning without having to clone it as you have shown above. – michael Oct 25 '12 at 20:27
  • @michael: Hmm... I doubt it. Knockout aims to be a lightweight JavaScript library, and I doubt that the library would clone arrays on your behalf if the documentation didn't explicitly say that it would. – Jim G. Oct 26 '12 at 13:28