【问题标题】:Delete Item from List using Knockout.js使用 Knockout.js 从列表中删除项目
【发布时间】:2012-02-01 00:54:19
【问题描述】:

我正在尝试从列表中删除一个项目。我正在使用带有映射插件的 knockout.js。我的代码如下所示:

序列化为 Json

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

模板

<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>

HTML

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

问题

一切都按预期进行。但是,当您单击按钮项时,会显示带有删除按钮的图像列表。文件名未定义。想法?

编辑:摘自 KNockout.js 手册:“当调用您的处理程序时,Knockout 将提供当前模型值作为第一个参数。如果您为集合中的每个项目呈现一些 UI,这将特别有用,并且您需要知道点击了哪个项目的 UI。”

看来我没有取回我期待的 Img 对象。我不知道我得到了什么!

【问题讨论】:

    标签: asp.net-mvc-3 knockout.js knockout-mapping-plugin


    【解决方案1】:

    我注意到这里有一个如何执行此操作的示例:

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

    查看4。更清晰的事件处理部分,Steve 展示了从列表中删除项目的示例。

    <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());
    

    但请注意,以上示例适用于最新版本的 KnockoutJS 2.0。

    【讨论】:

    • 是的,当我这样做时,它就像一个冠军。问题是当我使用模板时它停止工作。
    • 看来您使用的是 jQuery 模板,它的作用与带有 KO 的原生模板不同。你想用哪个?
    • @Jason,你应该使用 KO 原生模板。 jquery.tmpl 是一种死气沉沉的技术,未来没有更新计划。
    • 我想知道该怎么做,因为我读到 jquery.tmpl 已被弃用。它仍在 KO github 中,所以我认为 KO 社区现在正在支持它或其他什么。很高兴发现 KO 有原生支持,我可以删除 tmpl。
    【解决方案2】:

    当您在 jQuery 模板中使用 {{each}} 语法时,数据上下文是整个模板所绑定的任何内容。在您的情况下,这就是整个视图模型。

    几个选项:

    1- 你可以使用你当前的代码并将你“eaching”的项目传递给函数,比如(http://jsfiddle.net/rniemeyer/qB9tp/1/):

    <div data-bind="click: function() { $root.deleteImage($value); }">Delete</div>
    

    在数据绑定中使用异常函数是相当丑陋的。有更好的选择。

    2-你可以使用模板绑定的foreach参数,它适用于jQuery模板并且比{{each}}更高效(http://jsfiddle.net/rniemeyer/qB9tp/2/):

    <script type="text/html" id="imgsList">
        <div style="float:left; margin: 10px 10px 10px 0;">
            <div>
                <a href="${Filename}">${Filename}</a>
            </div>
            <div data-bind="click: $root.deleteImage">Delete</div>
        </div>
    </script>
    
    <div data-bind="template: { name: 'imgsList', foreach: model.Imgs }"></div>
    

    现在,模板的上下文是单个图像对象,调用 $root.deleteImage 会将其作为第一个参数传递。

    3- 由于不推荐使用 jQuery 模板插件,并且 Knockout 现在支持原生模板,您可能希望选择删除对 j​​Query 模板插件的依赖。您仍然可以使用命名模板(只需将任何 jQuery 模板语法替换为数据绑定属性),例如:http://jsfiddle.net/rniemeyer/qB9tp/3/ 甚至删除模板并使用foreach 控制流绑定,例如:http://jsfiddle.net/rniemeyer/qB9tp/4/

    <div data-bind="foreach: model.Imgs">
        <div style="float:left; margin: 10px 10px 10px 0;">
            <div>
                <a data-bind="text: Filename, attr: { href: Filename }"></a>
            </div>
            <div data-bind="click: $root.deleteImage">Delete</div>
        </div>
    </div>
    

    4- 虽然我更喜欢选项 #3,但您甚至可以选择使用事件委托并附加一个“实时”处理程序,例如:http://jsfiddle.net/rniemeyer/qB9tp/5/

    $("#main").on("click", ".del", function() {
       var data = ko.dataFor(this);
       viewModel.deleteImage(data); 
    });
    

    如果您要通过click 绑定(例如在网格中)附加大量相同的处理程序,这将特别有用。

    【讨论】:

    • 惊人的答案。在阅读了关于 jquery.tmpl 的弃用之后,我最终选择了 3.2。不过,我没有意识到 KO 现在有原生支持。很高兴我现在有所有这些选择。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多