使用 Knockout.js 从列表中删除项目

发布于 2024-12-23 14:13:36 字数 1291 浏览 0 评论 0原文

我正在尝试从列表中删除一个项目。我将 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>

KO 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。”

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

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别闹i 2024-12-30 14:13:36

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

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。

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.

或十年 2024-12-30 14:13:36

当您在 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 绑定(就像在网格中一样)的相同处理程序。

When you use {{each}} syntax in jQuery Templates, the data context is whatever the overall template is bound against. In your case, that is the entire view model.

A few options:

1- you can use your current code and pass the item that you are "eaching" on to the function like ( http://jsfiddle.net/rniemeyer/qB9tp/1/ ):

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

Using an anomymous function in the data-bind is pretty ugly though. There are better options.

2- you can use the foreach parameter of the template binding, which works with jQuery Templates and is more efficient than {{each}} like ( 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>

Now, the context of the template is the individual image object and calling $root.deleteImage will pass it as the first argument.

3- Since, the jQuery Templates plugin is deprecated and Knockout now supports native templates, you might want to choose removing your dependency on the jQuery Templates plugin. You could still use a named template (just need to replace any jQuery Templates syntax with data-bind attributes) like: http://jsfiddle.net/rniemeyer/qB9tp/3/ or even remove the template and just go with the foreach control-flow binding like: 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- While I prefer option #3, you could even choose to use event delegation and attach a "live" handler like: http://jsfiddle.net/rniemeyer/qB9tp/5/

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

This can be especially beneficial if you would be attaching a large number of the same handlers via the click binding (like in a grid).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文