I am having problems with a Knockout ObservableArray that is made up of objects with observable properties. My view model is fairly complicated but I have created the simple test below which will illustrate the problem.
My problem is that when I change the value of an observable property in one of the objects in the ObservableArray that value is changed for ALL objects in the array.
I have a department viewModel which has an observable array of employees in that department. I then create 5 instances of the object personVM that gets pushed onto the employees ObservableArray. Each instance of personVM gets a unique firstName.
Here are the models and the code to load them up.
var theDepartmentVM = {
employees: ko.observableArray(),
departmentName: ko.observable()
};
var personVM= {
firstName: ko.observable()
}
$(document).ready(function (){
departmentVM.departmentName = "SomeDepartment";
for (i=1; i<=5; i++){
var person = Object.create(personVM);
personVM.firstName("EMP - " + i.toString());
departmentVM.employees.push(personVM);
}
ko.applyBindings(departmentVM);
});
This adds five name (EMP-1, EMPT-2, etc.). Then I display the names with the following markup:
<div data-bind="foreach: employees">
<label data-bind="text: firstName"></label>
</div>
My output is the name "EMP-5" five times. It's always the last value I added to the array.
I think the problem is that I have five instances of personVM but the firstName object in each instance points to the same observable. Is this correct?
What do I need to do to get the desired result?
Try this
http://jsfiddle.net/r9sqjojL/2/
<div data-bind="foreach: employees">
<label data-bind="text: firstName"></label>
</div>
var departmentVM = {
employees: ko.observableArray(),
departmentName: ko.observable()
};
var personVM = function() {
this.firstName = ko.observable();
}
departmentVM.departmentName = "SomeDepartment";
for (i=1; i<=5; i++){
var person = new personVM();
person.firstName("EMP - " + i.toString());
departmentVM.employees.push( person );
}
ko.applyBindings(departmentVM);