简体   繁体   中英

KnockoutJS : How do I remove an item from a child array?

Issue:

I'm still learning knockoutJS, please guide me if my approach is wrong.

Here is my fiddle: http://jsfiddle.net/amitava82/wMH8J/25/

While onclick of edit, I receive the json model which is represented in the view and I want to remove certain items (child array) or actions (parent array) from the model (I removed add UI to add more Actions from the fiddle for simplicity) and then finally pass the model back to server.

Now, deleting from root level is easy. I'm stuck with deleting individual item which is ActionParamaters in ActionItems array.

Question:

How do I remove an item from a child array?

You can pass the clicked actionItem and the containing action array to deleteActionItem function as follows:

<!-- /ko -->
<a href="javascript:void(0)" data-bind="click: $root.deleteActionItem.bind($data, $parent)">remove item</a>

In your model you need to make every actionItem array observable using ko.mapping plugin (see edit function)

var viewModel = function() {
    var self = this;
    self.data = ko.observable();

    self.edit = function() {
       self.data ( ko.mapping.fromJS(editData) );
    }
    self.log = function() {
        console.log(self.data())
    }
    self.deleteAction = function(data) {
       //delete root node
       self.data().remove(data)
    }
    self.deleteActionItem = function(data,actionItem) {
        //delete items
        data.ActionItems.remove(actionItem);
    }
}

Then you will be able to remove the item from array in the deleteActionItem function and since the array is observable now, the result will reflect to binded dom element.

Sam, your fiddle data was too complicated. When asking questions, you will improve your chance of getting help if you distill your fiddle down to the relevant elements. I have cooked up a simple fiddle that illustrates nested arrays, and removal.

Here is the HTML, note that the remove function is inside the context of the array, so it calls a function on $parent instead of $root . This lets us target the context directly above, instead of the root.

<ul data-bind="foreach: editData">
    <li>
        <span data-bind="text: name"></span>
        <button data-bind="click: $parent.removeParent">Remove Parent</button>
        ...
            <!-- This line is on the child context -->
            <button data-bind="click: $parent.removeChild">Remove Child</button>

</ul>​

Here is the parent model. Note the removal function here is for removing children. When the removeChild function is called, it is from the child context asking for $parent , which will call this remove.

var Parent = function(name, children) {
    var self = this;
    self.name = ko.observable(name);
    self.children = ko.observableArray(children);
    self.removeChild = function(child) {
        self.children.remove(child);
    };
};

Your fiddle also makes no use of models, which are an important aspect of MVVM development. You should consider going through the tutorials on the knockout site to get a better understanding of how to structure knockout applications. It will help you deal with problems like this much easier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM