0

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?

1 Answer 1

2

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);
Sign up to request clarification or add additional context in comments.

2 Comments

That's the answer. Can you explain why this works? Do my objects need to be functions so they can use the 'this' object?
Yes, functions are so called "classes" that you can create new instances of, and within those functions, this refers to the specific instance's property. If you look at knockout's homepage tutorials, then this is how they do it too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.