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>
Items in an observableArray
don't themselves automatically become observable. You'll have to map your objects into Item
s 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 Item
s.