3

I have some trouble with knockout nested observableArrays.

My Data looks like this:

var myData = {
    Id: 123,
    Name: "string here",
    Categories: [
       {
           Id: 12,
           Name: "Category Name",
           Products: [
               {
                  Id: 1,
                  Name: 'Product1 name',
                  SomethingElse: '...'
               },
               {
                  Id: 2,
                  Name: 'Product2 name',
                  SomethingElse: '...'
               }
           ]
       },{
           // another category ...
       }
    ]
}

My ViewModel looks like this:

 viewModel = function () {
     var self = this;
     this.Id = menueItem ? ko.observable(menueItem.Id) : ko.observable(0);
     this.Name = menueItem ? ko.observable(menueItem.Name) : ko.observable();
     this.Categories = menueItem ? ko.observableArray(menueItem.Categories) : ko.observableArray([]);
     // ...
 }

So my question is, how get the Products of each Category also to an observableArray. The properties in Products not have to be observable. In my Application I have to add and remove Categories and Products.

chris
  • 4,827
  • 6
  • 35
  • 53

1 Answers1

4

Create viewmodels for categories & products. categoryViewModel should contain a function to add products and the root viewmodel should contain a function to add categories:

Root viewmodel:

viewModel = function () {
    var self = this;

    menuItem = menuItem || {
        Id: 0,
        Name: null,
        Categories: []
    };

    this.Id = ko.observable(menueItem.Id);
    this.Name = ko.observable(menueItem.Name);
    this.Categories = ko.observableArray();

    this.addCategory = function(category) {
        self.Categories.push(new categoryViewModel(category));
    }

    // create category viewmodels and add them to this root viewmodel
    for (var i = 0, l = menuItem.Categories.length; i < l; i++) {
        self.addCategory(menuItem.Categories[i]);
    }
     // ...
}

Category viewmodel:

categoryViewModel = function(categoryObj) {  
    var self = this;

    categoryObj = categoryObj || {
        Id: 0,
        Name: null,
        Products: [],
    };
    this.Id = ko.observable(categoryObj.Id);
    this.Name = ko.observable(categoryObj.Name);
    this.Products = ko.observableArray();

    this.addProduct = function(product) {
        self.Products.push(new productViewModel(product);
    }

    // create product viewmodels and add them to this category viewmodel
    for (var i = 0, l = categoryObj.Products.length; i < l; i++) {
        self.addCategory(categoryObj.Products[i]);
    }
}

Product viewmodel:

productViewModel = function(productObj) {  
    var self = this;

    productObj = productObj || {
        Id: 0,
        Name: null,
        SomethingElse: null,
    };
    this.Id = productObj.Id;
    this.Name = productObj.Name;
    this.SomethingElse = productObj.SomethingElse;
}

You will have:

viewmodel {
    Id(),
    Name(),
    Categories() : [
        categoryViewModel = {
            Id(),
            Name(),
            Products(): [
                productViewModel = {
                    Id,
                    Name,
                    SomethingElse
                }
                ...
            ]
        },
        ...
    ]
}
manji
  • 47,442
  • 5
  • 96
  • 103