前段时间我关注了 Knockout 教程,其中一个 http://learn.knockoutjs.com/#/?tutorial=collections
详细说明如何创建列表和集合。但是我想在列表中创建一个级联下拉选择。
我的问题是,您可以使用淘汰赛在这样的动态列表中创建级联下拉列表吗?
碰巧的是,经过几个小时的研究,我实际上已经设法解决了这个问题,因此将其添加到此处作为答案,因为我认为它可能对某人有用。也许有更好的方法来做到这一点?
前段时间我关注了 Knockout 教程,其中一个 http://learn.knockoutjs.com/#/?tutorial=collections
详细说明如何创建列表和集合。但是我想在列表中创建一个级联下拉选择。
我的问题是,您可以使用淘汰赛在这样的动态列表中创建级联下拉列表吗?
碰巧的是,经过几个小时的研究,我实际上已经设法解决了这个问题,因此将其添加到此处作为答案,因为我认为它可能对某人有用。也许有更好的方法来做到这一点?
它会起作用,但我只想添加一件事:小缓存。基本上,一旦您加载了可用于给定餐点的餐点,您就可以在餐点对象中创建一个属性来存储它们。这样,后续调用可能会知道这些餐点已经加载。我为此创建了一个可观察的数组,如下所示:
给定这个模拟从服务器检索数据的函数:
var mealTypesByKey = [];
mealTypesByKey[1] = [{ mealName: "Vegemite Sandwich", price: 4.00, mealType: 1},
{ mealName: "Cheese Sandwich", price: 34.95,mealType: 2 },
{ mealName: "Jam Sandwich", price: 290, mealType: 3 } ];
mealTypesByKey[2] = [{ mealName: "Standard (Ham)", price: 15, mealType: 1},
{ mealName: "Chicken Wrap (Possibly rat)", price: 15, mealType: 1} ];
mealTypesByKey[3] = [{ mealName: "Premium (lobster)", price: 34.95,mealType: 2 },
{ mealName: "Ultimate (whole zebra)", price: 290, mealType: 3 } ];
function serverGetMealsForType(key) {
return mealTypesByKey[key];
}
您可以定义以下可订阅函数:
self.mealType.subscribe(function(newMealType) {
if(!newMealType.meals) {
newMealType.meals = ko.observableArray([]);
newMealType.meals(serverGetMealsForType(newMealType.key));
console.log("meals loaded");
} else {
console.log("meals already available for meal type " + newMealType.key);
}
});
这样,动态列表就会使用给定的绑定正确地重新创建:
<td><select data-bind="options: mealType().meals, value: meal, optionsText: 'mealName'"></select></td>
这是避免不必要的服务器调用的一种常见且简单的技术。
编辑:忘记添加我 fork 的小提琴。
我从 learn.knockoutjs.com 获取了收藏教程的原始版本。我决定添加一个膳食类型选择,在选择时更改可用的膳食。
我发现可用的饭菜需要移动到单独的列表项中,因为它会改变每个
function SeatReservation(name, initialMeal, initialMealType) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
// Non-editable catalog data - would come from the server
self.availableMeals = ko.observableArray([
{ mealName: "Standard (sandwich)", price: 0, mealType: 1},
{ mealName: "Premium (lobster)", price: 34.95,mealType: 2 },
{ mealName: "Ultimate (whole zebra)", price: 290, mealType: 3 }
]);
我还在个人预订中创建了一种膳食类型:
self.mealType= ko.observable();
然后是可用膳食类型的列表:
// Non-editable catalog data - would come from the server
self.availableMealTypes = [
{ mealTypeName: "Vege", key: 1 },
{ mealTypeName: "Dead Animal", key: 2 },
{ mealTypeName: "Meat Whore", key: 3}
];
然后绑定到 HTML 中。
最后,我订阅了餐食类型的更改,并在此函数中修改了可用餐食集合:
self.mealType.subscribe(function() {
if (self.mealType().key == 1)
{
self.availableMeals ([
{ mealName: "Vegemite Sandwich", price: 4.00, mealType: 1},
{ mealName: "Cheese Sandwich", price: 34.95,mealType: 2 },
{ mealName: "Jam Sandwich", price: 290, mealType: 3 } ]);
}
最终和完整的解决方案可以在这个 jsFiddle中看到。