我想显示项目的可编辑列表,其中每个项目是可编辑的(有点像一个编辑网格,在某种程度上)。 我使用KnockoutJS。 我不能使用只是一个简单的可观察阵列,因为随着文档状态“一个observableArray轨道哪些对象是在阵列中,这些对象的不是状态”
所以,我创建了(使用utils.arrayMap)观察对象的observableArray,并将其绑定到视图。 然而,问题是,如果我编辑屏幕上的数据,所有数据输入改变了用户对屏幕没有出现生效。 见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);
});
ko.utils.arrayMap不作为观测您的视图模型的属性映射,这就是为什么你没有看到他们动态更新。
如果你定义类别编号为可观察,你会看到它更新预期:
var initialData = [
{
Name: "Television",
CategoryId: ko.observable("1")
},
{
Name: "Melon",
CategoryId: ko.observable("2")
}
];
看到这个更新的jsfiddle: http://jsfiddle.net/tuando/E7xPM/5/
为了跟进疃的答案,我需要基于从服务器方法从一个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);
});
谢谢,抟!
我使用的是在调用初始化ko.utils.arrayMap计算写观测
可能你的情况矫枉过正,但它可能会帮助别人。 看到这个的jsfiddle样本
// Writeable computed observables
function Customer(id, firstName, lastName, preferred) {
var self = this;
self.id = id;
self.firstName = firstName;
self.lastName = lastName;
// Non-Writeable computed observable
self.fullName = ko.computed(function() {
var fn = self.firstName;
var ln = self.lastName;
return ln ? fn + ' ' + ln : fn;
}, self);
self.preferred = ko.observable(preferred);
// Writeable computed observable
self.isPreferred = ko.computed({
read: function() {
var preferredStr = self.preferred() || '';
var isPreferredComputed = preferredStr.toUpperCase();
return (isPreferredComputed === 'Y') ? true : false;
},
write: function(value) {
self.preferred( (!value) ? '' : (value ? 'Y' : ''));
},
owner: self
});
}
var mappedData = ko.utils.arrayMap(dataFromServer, function(customer) {
return new Customer(customer.id, customer.firstName, customer.lastName, customer.preferred);
});