【问题标题】:How to create a cascading select dropdown in a dynamic list using Knockout MVC如何使用 Knockout MVC 在动态列表中创建级联选择下拉菜单
【发布时间】:2013-05-17 17:00:12
【问题描述】:

我前段时间关注了 Knockout 教程中的哪一个 http://learn.knockoutjs.com/#/?tutorial=collections

详细说明如何创建列表和集合。 但是我想在列表中创建一个级联下拉选择。

我的问题是,您能否在这样的动态列表中使用淘汰赛创建级联下拉菜单?

碰巧的是,经过几个小时的研究,我实际上已经设法解决了这个问题,因此将其添加到此处作为答案,因为我认为它可能对某人有用。也许有更好的方法?

【问题讨论】:

    标签: knockout.js cascadingdropdown dynamic-list


    【解决方案1】:

    它会起作用,但我只想添加一件事:小型缓存。基本上,一旦您加载了可用于给定餐点的餐点,您就可以在餐点对象中创建一个属性来存储它们。这样,后续调用可能会知道这些餐点已经加载。我为此创建了一个可观察数组,如下所示:

    给定这个模拟从服务器检索数据的函数:

    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>
    

    这是避免不必要的服务器调用的一种常见且简单的技术。

    编辑:忘记添加fiddle I've forked

    【讨论】:

    • 我已经添加了你的答案的一个稍微修改的版本,它使用 KO Computed 而不是订阅:jsfiddle.net/MEwsU 这是一个比任何东西都重要的教育练习。
    【解决方案2】:

    我从 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 }    ]);
        }
    

    最终完整的解决方案可见this jsFiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-14
      • 2022-08-11
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      相关资源
      最近更新 更多