And*_*mas 29 observable ko.observablearray knockout.js
我想显示一个可编辑的项目列表,每个项目都是可编辑的(在某种程度上类似于可编辑的网格).我正在使用KnockoutJS.我不能只使用一个简单的Observable Array,因为文档声明"一个observableArray跟踪数组中的哪些对象,而不是那些对象的状态"
因此,我创建了一个observableArray的可观察对象(使用utils.arrayMap),并将它们绑定到视图.但问题是,如果我在屏幕上编辑数据,则用户在屏幕上进行的任何数据输入更改似乎都不会生效.见http://jsfiddle.net/AndyThomas/E7xPM/
我究竟做错了什么?
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js" type="text/javascript"></script>
<table>
<tbody data-bind="template: { name:'productListJavascriptTemplate', foreach: products}">
</tbody>
</table>
<script type="text/html" id="productListJavascriptTemplate">
<tr>
<td>Name: <input data-bind="value: Name"/></td>
<td>Name: <span data-bind="text: Name"/></td>
<td><select data-bind="options: this.viewModel.categories,
optionsText: 'Name', optionsValue: 'Id', value: CategoryId,
optionsCaption: 'Please select...'"></select></td>
<td>CategoryId: <input data-bind="value: CategoryId"/></td>
</tr>
</script>?
var categoryList= [
{
Name: "Electronics",
Id: "1"},
{
Name: "Groceries",
Id: "2"}
];
var initialData= [
{
Name: "Television",
CategoryId: "1"},
{
Name: "Melon",
CategoryId: "2"}
];
var viewModel = {
products: ko.observableArray(
ko.utils.arrayMap(initialData, function(product) {
return ko.observable(product);
})),
categories: ko.observableArray(categoryList)
};
$(function() {
ko.applyBindings(viewModel);
});
Run Code Online (Sandbox Code Playgroud)
Tua*_*uan 19
ko.utils.arrayMap不会将您的viewmodel属性映射为observables,这就是您没有看到它们动态更新的原因.
如果将CategoryId定义为observable,您将看到它按预期更新:
var initialData = [
{
Name: "Television",
CategoryId: ko.observable("1")
},
{
Name: "Melon",
CategoryId: ko.observable("2")
}
];
Run Code Online (Sandbox Code Playgroud)
看到这个更新的jsfiddle:http://jsfiddle.net/tuando/E7xPM/5/
And*_*mas 16
为了跟进Tuan的回答,我需要根据从ASP.Net MVC控制器的服务器方法返回的数据来填充我的对象,其中产品列表包含在视图的模型中,以及下拉列表的类别列表框在ViewBag中.我使用了以下代码(另请参见http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html):
var initialData = @Html.Raw( new JavaScriptSerializer().Serialize(Model));
var categoryList = @Html.Raw( new JavaScriptSerializer().Serialize(ViewBag.CategoryList));
var ObservableProduct = function(name, description, categoryId) {
this.Name = ko.observable(name);
this.Description = ko.observable(description);
this.CategoryId = ko.observable(categoryId);
};
var viewModel = {
products: ko.observableArray(ko.utils.arrayMap(initialData, function(product) {
return new ObservableProduct(product.Name, product.Description, product.CategoryId);
})),
categories: ko.observableArray(categoryList)
};
$(function() {
ko.applyBindings(viewModel);
});
Run Code Online (Sandbox Code Playgroud)
谢谢,Tuan!