【发布时间】:2018-12-10 14:42:13
【问题描述】:
我一直在阅读 Knockout 教程,当有什么让我困惑时,我正在玩一个教程。这是我的 HTML:
<h2>Your seat reservations</h2>
<table>
<thead><tr>
<th>Passenger name</th><th>Meal</th><th>Surcharge</th>
</tr></thead>
<tbody data-bind="foreach: seats">
<tr>
<td><input data-bind="value: name" /></td>
<td><select data-bind="options: $root.availableMeals, optionsValue: 'mealVal', optionsText: 'mealName', value: meal"></select></td>
<td data-bind="text: formattedPrice"></td>
</tr>
</tbody>
</table>
<button data-bind="click: addSeat">Reserve another seat</button>
...这是我的 JavaScript:
// Class to represent a row in the seat reservations grid
function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function() {
var price = self.meal().price;
return price ? "$" + price.toFixed(2) : "None";
});
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
// Non-editable catalog data - would come from the server
self.availableMeals = [
{ mealVal: "STD", mealName: "Standard (sandwich)", price: 0 },
{ mealVal: "PRM", mealName: "Premium (lobster)", price: 34.95 },
{ mealVal: "ULT", mealName: "Ultimate (whole zebra)", price: 290 }
];
// Editable data
self.seats = ko.observableArray([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0])
]);
// Operations
self.addSeat = function() {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}
}
ko.applyBindings(new ReservationsViewModel());
当我运行此示例并从下拉菜单中为乘客选择不同的“餐食”时,“附加费”值未更新。此原因似乎是我在select 987654326 select的select,而且当我删除时,在选择新的下拉选项时,“额外收费”确实更新。但是为什么添加optionsValue 会破坏更新?所做的只是设置select 列表的选项value 属性,这对于表单提交非常有用——我不明白为什么它会阻止Knockout 自动更新。
更新:经过进一步调查,我发现 formattedPrice fn 仍在被调用,但 self.meal() 现在解析为值字符串,例如 PRM 而不是全餐对象。但这是为什么呢?文档说 optionsValue 在 HTML 中设置了 value 属性,但没有说明更改视图模型的行为。
我认为发生的情况是,当您指定 options: $root.availableMeals 但未指定 optionsValue 时,Knockout 会神奇地确定您在更改选择时所做的列表中的哪个选择,并允许您访问object 来自availableMeals 而不仅仅是放入value 属性的字符串值。这似乎没有很好的记录。
【问题讨论】:
-
在文档here 中有一小段解释
optionsValue。 “通常,您只想使用 optionsValue 来确保 KO 在更新可用选项集时能够正确保留选择。”如果您自己的更新回答了您的问题,我建议将其发布为答案。如果您还有任何问题,请告诉我/我们还有什么不清楚的地方。 -
这仍然不清楚,因为它没有解释为什么当您设置
optionsValue时,formattedPrice函数从传入的全餐对象变成了optionsValue值。为什么不继续获取全餐对象?
标签: javascript html mvvm knockout.js