- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在浏览 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());
当我运行此示例并从下拉菜单中为乘客选择不同的“膳食”时,“附加费”值未更新。这样做的原因似乎是我将 optionsValue: 'mealVal'
添加到 select
的 data-bind
属性中,当我删除也就是说,当选择新的下拉选项时,“附加费”确实会更新。但为什么添加 optionsValue
会中断更新?所做的只是设置 select
列表的选项 value
属性,这对于表单提交非常有用 - 我不明白为什么它应该阻止 Knockout 自动更新。
更新:经过进一步调查,我发现 formattedPrice
fn 仍在被调用,但是 self.meal()
是现在解析为值字符串,例如 PRM
而不是整个 meal 对象。但这是为什么呢?文档说 optionsValue
在 HTML 中设置了 value
属性,但没有说明任何关于更改 View 模型行为的内容。
我认为发生的事情是,当您指定 options: $root.availableMeals
,但不指定 optionsValue
时,Knockout 会神奇地确定列表中的选择您在更改选择时所做的,并允许您从 availableMeals
访问 object 而不仅仅是放入 value
的字符串值> 属性。这似乎没有很好的记录。
最佳答案
我认为您了解发生了什么以及为什么它会破坏您的代码,但仍在寻找关于何时实际需要使用 optionsValue
以及何时不需要的解释。
optionsValue
绑定(bind)假设您的餐食可能已售罄,您希望通过服务器检查 availableMeals
中的更新:
const availableMeals = ko.observableArray([]);
const loadMeals = () => getMeals().then(availableMeals);
const selectedMeal = ko.observable(null);
loadMeals();
ko.applyBindings({ loadMeals, availableMeals, selectedMeal });
function getMeals() {
return {
then: function(cb) {
setTimeout(cb.bind(null, [{ mealVal: "STD", mealName: "Standard (sandwich)", price: 0 }, { mealVal: "PRM", mealName: "Premium (lobster)", price: 34.95 }, { mealVal: "ULT", mealName: "Ultimate (whole zebra)", price: 290 }]), 500);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: availableMeals,
value: selectedMeal,
optionsText: 'mealName'"></select>
<button data-bind="click: loadMeals">refresh meals</button>
<div data-bind="with: selectedMeal">
You've selected <em data-bind="text: mealName"></em>
</div>
<div data-bind="ifnot: selectedMeal">No selection</div>
<p>Make a selection, click on refresh and notice the selection is lost when new data arrives.</p>
当您替换 availableMeals
中的对象时会发生什么:
selectedMeal() === mealObject
的新值selectedMeal
中没有找到对象,默认第一个选项selectedMeal
问题:您丢失了 UI 选择,因为它指向的对象不再位于可用选项中。
optionsValue
助您一臂之力!optionsValue
让我们可以解决这个问题。我们没有存储对可能随时被替换的对象的引用,而是存储了一个原始值,即mealVal
中的字符串,它允许我们检查不同 API 调用之间的相等性! Knockout 现在会做类似的事情:
selection = newObjects.find(o => o["mealVal"] === selectedMeal());
让我们看看实际效果:
const availableMeals = ko.observableArray([]);
const loadMeals = () => getMeals().then(availableMeals);
const selectedMeal = ko.observable(null);
loadMeals();
ko.applyBindings({ loadMeals, availableMeals, selectedMeal });
function getMeals() {
return {
then: function(cb) {
setTimeout(cb.bind(null, [{ mealVal: "STD", mealName: "Standard (sandwich)", price: 0 }, { mealVal: "PRM", mealName: "Premium (lobster)", price: 34.95 }, { mealVal: "ULT", mealName: "Ultimate (whole zebra)", price: 290 }]), 500);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: availableMeals,
value: selectedMeal,
optionsText: 'mealName',
optionsValue: 'mealVal'"></select>
<button data-bind="click: loadMeals">refresh meals</button>
<div data-bind="if: selectedMeal">
You've selected <em data-bind="text: selectedMeal"></em>
</div>
<div data-bind="ifnot: selectedMeal">No selection</div>
<p>Make a selection, click on refresh and notice the selection is lost when new data arrives.</p>
optionsValue
的缺点请注意我必须如何重写 with
绑定(bind)?突然之间,我们的 View 模型中只有 meal
的一个属性可用,这是非常有限的。如果您希望您的应用程序能够更新其数据,那么您必须在此处执行一些额外的工作。您的两个选择:
如果有帮助,我可以添加代码片段来更好地解释这两种方法
关于javascript - 为什么设置 optionsValue 会中断 Knockout 更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51135005/
我有一个代码不起作用。这是这里 http://jsfiddle.net/JPBarbosa/uxwTM/4/ . 数据绑定(bind)参数 optionsValue 不像参数 optionsText
对于这段代码 function Order(name, initialMeal) { var self = this; self.name = name; self.meal
这是我当前的代码 var model = function() { this.nameSomething = ko.observable(''); this.nameId = ko.o
下面的代码经过简化,请参阅 fiddle :http://jsfiddle.net/QTUqD/7/ 基本上我是在数据绑定(bind)下设置设备名称,但我还需要指定发送到数据库的选项值,但是当我设置它
我正在使用knockout js 3.2,我对选择绑定(bind)的工作原理有基本的困惑 在上面的例子中,如果我们有一个类型的对象 var choices = [ { id: 'M'
我一直在浏览 Knockout 教程,当我在玩一个教程时,我感到困惑。这是我的 HTML: Your seat reservations Passenger nameMea
我想知道数据绑定(bind)、选项、optionsText 和 optionsValue 在这里是如何工作的? Here is the Fiddl
有没有办法保留value绑定(bind)到对象,但有 optionsValue成为对象的属性。截至目前,如果我同时指定两者,optionsValue选择的属性将填充 value捆绑。我想在 obser
在以下代码中,产品(用 productVM 表示)有一个可观察属性 (productName),其中包含其两种语言(英语和法语)的名称。 添加 cartItem 并选择产品后,我希望在单击“更改语言”
我是一名优秀的程序员,十分优秀!