Delete Item from List using Knockout.js

Jason picture Jason · Jan 2, 2012 · Viewed 8.5k times · Source

I am trying to delete an item from a list. I am using knockout.js with the mapping plugin. My code looks like this:

Serialize to Json

@{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model));}

Template

<script type="text/html" id="imgsList">
    {{each model.Imgs}}
        <div style="float:left; margin: 10px 10px 10px 0;">
            <div><a href="${Filename}"><img src="${Filename}" style="width:100px;"></img></a></div>
            <div data-bind="click: deleteImage">Delete</div>
        </div>
    {{/each}}
</script>

K.O. JavaScript

<script type="text/javascript">
     $(function() {
        //KO Setup
        var viewModel = { 
            "model": ko.mapping.fromJS(@jsonData),
            "deleteImage" : function(item) {alert(item.Filename + ' deleted.');}
        }

        ko.applyBindings(viewModel);
    });
</script>

The HTML

<div data-bind="template: 'imgsList'"></div>

The Question

Everything works as expected. A list of images shows up with delete buttons, however, when you click a button item.Filename is undefined. Thoughts?

Edit: Taken from the KNockout.js Manual: "When calling your handler, Knockout will supply the current model value as the first parameter. This is particularly useful if you’re rendering some UI for each item in a collection, and you need to know which item’s UI was clicked."

It appears that I am not getting back the Img object I am expecting. I don't know what I am getting back!

Answer

Jason Evans picture Jason Evans · Jan 3, 2012

I notice there is an example of how to do this here:

http://blog.stevensanderson.com/2011/12/21/knockout-2-0-0-released/

Check out the 4. Cleaner event handling section where Steve shows an example of an item being deleted from a list.

<h3>Products</h3>

<ul data-bind="foreach: products">
    <li>
        <strong data-bind="text: name"></strong>
        <button data-bind="click: $parent.removeProduct">Delete</button>
    </li>
</ul>

Javascript:

    function appViewModel() {
        var self = this;
        self.products = ko.observableArray([
            { name: "XBox" },
            { name: "PlayStation" },
            { name: "Banana" },
            { name: "Wii" }
        ]);

        self.removeProduct = function(product) {
            self.products.remove(product);   
        }
    };

ko.applyBindings(new appViewModel());

But take into account that the above example is for KnockoutJS 2.0 which is the latest release.