Как создать каскадный выпадающий список в динамическом списке с помощью Knockout MVC

Некоторое время назад я следовал учебникам по нокауту, один из которых http://learn.knockoutjs.com/

подробно, как создавать списки и коллекции. Однако я хочу создать каскадный выпадающий список в списке.

Мой вопрос был бы: можете ли вы создать каскадный выпадающий список в динамическом списке, подобный этому, используя нокаут?

Так получилось, что мне действительно удалось решить вопрос после нескольких часов его изучения, поэтому я добавлю его здесь в качестве ответа, так как я думаю, что это может быть полезно для кого-то. Может быть, есть лучшие способы сделать это?

2 ответа

Решение

Это бы сработало, но я бы добавил одно: небольшое кэширование. По сути, как только вы загрузили блюда, доступные для данного блюда, вы можете создать свойство в вашем объекте еды для их хранения. Таким образом, последующие звонки могут знать, что эти блюда уже загружены. Я создал наблюдаемый массив для этого, например, так:

Учитывая эту функцию, которая имитирует получение данных с сервера:

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>

Это обычная и простая техника, позволяющая избежать ненужных обращений к серверу.

Изменить: забыл добавить скрипку, которую я раздвоил.

Я взял оригинальную версию учебника по коллекциям с 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.

Другие вопросы по тегам