Jas*_*son 4 asp.net-mvc-3 knockout-mapping-plugin knockout.js
我想从列表中删除一个项目.我正在使用knockout.js与映射插件.我的代码看起来像这样:
@{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model));}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
<div data-bind="template: 'imgsList'"></div>
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作.但是,当您单击按钮项时,将显示带有删除按钮的图像列表.未定义文件名.思考?
编辑:取自KNockout.js手册:"当调用你的处理程序时,Knockout将提供当前模型值作为第一个参数.如果你为一个集合中的每个项目渲染一些UI,这是特别有用的,你需要知道哪个项目的用户界面被点击了."
看来我没有收到我期待的Img对象.我不知道我要回来了!
我注意到这里有一个如何做到这一点的例子:
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>
Run Code Online (Sandbox Code Playgroud)
使用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());
Run Code Online (Sandbox Code Playgroud)
但考虑到上面的例子是针对最新版本的KnockoutJS 2.0.
在jQuery模板中使用{{each}}语法时,数据上下文是整个模板绑定的任何内容.在您的情况下,这是整个视图模型.
一些选择:
1-您可以使用当前代码并将您正在"关注"的项目传递给函数,如(http://jsfiddle.net/rniemeyer/qB9tp/1/):
<div data-bind="click: function() { $root.deleteImage($value); }">Delete</div>
Run Code Online (Sandbox Code Playgroud)
在data-bind中使用anomymous函数非常难看.有更好的选择.
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>
Run Code Online (Sandbox Code Playgroud)
现在,模板的上下文是单个图像对象,调用$root.deleteImage将它作为第一个参数传递.
3-因为,jQuery Templates插件已弃用,Knockout现在支持本机模板,您可能希望选择删除对jQuery Templates插件的依赖.您仍然可以使用命名模板(只需要用数据绑定属性替换任何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>
Run Code Online (Sandbox Code Playgroud)
4-虽然我更喜欢选项#3,但你甚至可以选择使用事件委托并附加一个"实时"处理程序,如:http://jsfiddle.net/rniemeyer/qB9tp/5/
$("#main").on("click", ".del", function() {
var data = ko.dataFor(this);
viewModel.deleteImage(data);
});
Run Code Online (Sandbox Code Playgroud)
如果您通过click绑定附加大量相同的处理程序(如在网格中),这可能特别有用.
| 归档时间: |
|
| 查看次数: |
8385 次 |
| 最近记录: |