1

I have a below code for knockout binding:

HTML:

   <div data-bind="visible: people().length > 0">
    <div data-bind="foreach: people"> <span data-bind="text: title"></span>
 <span data-bind="text: forename"></span>
 <span data-bind="text: surname"></span>

        <button data-bind="click: $root.removePerson">Remove</button>
        <br />
    </div>
</div>
<div data-bind="with: Person">
    <input type="text" data-bind="value: title" />
    <input type="text" data-bind="value: forename" />
    <input type="text" data-bind="value: surname" />
    <button data-bind="click: $root.addPerson">Add</button>
</div>

Javascript:

   var my = my || {};
Person = function () {
    var self = this;
    self.title = ko.observable(null);
    self.forename = ko.observable(null);
    self.surname = ko.observable(null);
};
my.vm = function () {
    var people = ko.observableArray([]),
        addPerson = function (jh) {
            people.push(jh);
        },
        removePerson = function (jh) {
            people.remove(jh);
        };
    return {
        people: people,
        addPerson: addPerson,
        removePerson: removePerson
    };
}(new Person());

ko.applyBindings(my.vm);

I am struggling to add Person object into an observable array (people) and display it on top to create an array of people with add and remove functionality in it.

jsFiddle here

Can someone please advise what am I missing?

Update: I have tidied up code a little bit, now the issue can be seen on fiddle, that adding a single object update all the array objects and removing an object removes all the objects from array which is the problem. Thank for the help.

4
  • 1
    Is that just a typo where you have people = function (p) rather than addPerson = function (p)? Are you seeing errors or what problem are you having? Commented Jan 9, 2014 at 19:52
  • I see a number of mistakes in this code. The one mentioned by RP Niemeyer, also you call applyBindings with 'my.vm'. In your bindings, this is considered the $root binding context. So your databindings that start with my. or vm. won't work. Also, you define my.Person as a function, then use it as the value of a with-binding. This makes no sense to me. Additionally, I don't get the part (new my.Person()); that you put behind the function my.vm. Commented Jan 9, 2014 at 21:17
  • @RPNiemeyer you guessed it right. Sorry I corrected the typo and created a js fiddle. Commented Jan 9, 2014 at 23:12
  • @Hans "new my.Person())" is there to add an initial object when viewmodel is loaded. I am trying to get the scope right, but it is giving an error: Cannot read property 'vm' of undefined. Commented Jan 9, 2014 at 23:24

2 Answers 2

4

The issue that you are having is that you are always dealing with a single instance of a Person. So, you are adding, updating, and removing the same instance.

A better approach might be to use something like a personForEditing observable that contains a new person. Then, when doing addPerson you would add this person to the observableArray and replace personForEditing with a new instance for the next entry. Based on your code something like:

my.vm = function () {
    var people = ko.observableArray([]),
        addPerson = function (jh) {
            people.push(jh);
            personForEditing(new Person());
        },
        removePerson = function (jh) {
            people.remove(jh);
        },
        personForEditing = ko.observable(new Person())
    return {
        people: people,
        addPerson: addPerson,
        removePerson: removePerson,
        personForEditing: personForEditing
    };
}();

updated sample: http://jsfiddle.net/rniemeyer/xms4d/

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! Thanks RP Niemeyer. Answer from a knockout expert works like a charm :)
0

You are reassigning the variable people.

First it is set to an observable then to a function.

So the fault is here:

var people = ko.observableArray([]),
    people = function (p) {
        people.push(p);
    }, ... ;

1 Comment

this was a typo found by RP Niemeyer, I have corrected that and created and jsFiddle as well. Still no joy :(

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.