Question

I am working in application which have feautres like add a new row,delete a new row .All the things are working fine.Like for the very first time i am loading data from the items(i have so many viewmodel bind in a single page), there all the data seems to be working as expected (whenever the values are edited , updated in my view model).But when i load the existed data for the second time, the viewmodel is not updated as expected.the view model is holding the same data even i edited the data.i think the observable is not working properly.Kindly tell where exactly i am doing the mistake.

First time :

function ViewModel() {
    var self = this;

    //Available types - which will come from serverside
    self.typeDropDown = ko.observableArray(InitialData);

    self.typeValue = ko.observable();

//Explicitly Adding new Row
    self.Inputs = ko.observableArray([new Item(self.typeDropDown[0], '', '', '')]);

    self.removeRow = function (Item) {
        self.Inputs.remove(Item);
    },
    self.addNewRow = function () {
        //push will add a new element to the container without modifying much in DOM
        self.Inputs.push(new Item(self.typeDropDown[0], '', '', ''));
    }


function Item(Type, StrData, MaxData, Back) {
    var self = this;
    self.Type = ko.observable(Type),
    self.Storage = ko.observable(StrData),
    self.MaxIOPS = ko.observable(MaxData),
    self.BackupPercentagePerMonth = ko.observable(Back)
}

Second Time - Loading data from Server.

Sample Input structure from server :

strJSON = [
   {
       Type: storageInitialData[0].Value,
       Str: '12',
       Max: '156',
       Back: '123'
   },
    {
       Type: storageInitialData[0].Value,
       Str: '12',
       Max: '156',
       Back: '123'
   }, {
       Type: storageInitialData[0].Value,
       Str: '12',
       Max: '156',
       Back: '123'
   }
];


function ViewModel() {
    var self = this;

    //Available types - which will come from serverside
    self.typeDropDown = ko.observableArray(InitialData);

    self.typeValue = ko.observable();

//Explicitly Adding new Row
    self.Inputs = ko.observableArray(strJSON);

    self.removeRow = function (Item) {
        self.Inputs.remove(Item);
    },
    self.addNewRow = function () {
        //push will add a new element to the container without modifying much in DOM
        self.Inputs.push(new Item(self.typeDropDown[0], '', '', ''));
    }

Is ko.observableArray(strJSON) is not enough to set observable property for the elements in array? Do i need to call the Item method again?

Update

my dropdown goes like this

<select class="ddText" id="selType" style="width: 100px"
                            data-bind="options:typeDropDown, optionsText: 'Value', optionsValue: 'Value',value : (Type.Value)?Type.Value : Type,attr: { name: 'str',id : 'strType_'+$index()}, uniqueName:true" ">
                        </select>
Was it helpful?

Solution

Items in an observableArray don't themselves automatically become observable. You'll have to map your objects into Items before adding them to Inputs. ko.utils.ArrayMap (or the built-in map method of arrays if you can be sure you're running in an ES5 browser) will be helpful here. You might also want to look into the ko.mapping plugin (which is officially supported); in your case it would generate the equivalent of mapping the entries to Items.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top