淘汰赛三个叠水下拉菜单(Knockout three cascading dropdowns)

2019-09-28 18:26发布

我真的很喜欢在活生生的例子cartEditor 。 这正是我需要的。 嗯,差不多,如果我想要什么再添下拉。 例如,如果我想要添加到现有的例子另一个领域country 。 该方案是这样的:我选择的国家,车辆类别,并根据此选择车辆本身。 如何将两个下拉菜单绑定到第三?

表中关于这些数据库:

表车辆

ID名称countryId的categoryId

表类别

ID名称

表国家

ID名称

一个活生生的例子文件位于knockoutjs.com

Answer 1:

你会继续使用相同的原则:

  • 限定在一个阵列或普通对象数据
  • 构建你的ViewModels,使数据渲染和可选择
  • 创建ko.pureComputed选择基于用户输入的数据子集的属性

例如,假设您的产品同时具有categorycountry

var products = [
  { 
    name: "Cheese",
    country: "The Netherlands",
    category: "Dairy"
  }
]

现在,如果你有两个观测,绑定到您的UI:

this.selectedCountry = ko.observable();
this.selectedCategory = ko.observable();

您可以创建一个ko.pureComputed ,使一个选择的符合要求的产品:

this.selectedProducts = ko.pureComputed(function() {
  return products.filter(function(product) {
    return product.category === this.selectedCategory() &&
           product.country === this.selectedCountry();
  });
}, this);

例:

 var products = [ { name: "Gouda Cheese", country: "The Netherlands", category: "Dairy" }, { name: "Camambert", country: "France", category: "Dairy" }, { name: "Red Wine", country: "France", category: "Alcoholic beverages" } ]; var ViewModel = function() { // These will be bound to your dropdowns' selections this.selectedCountry = ko.observable(); this.selectedCategory = ko.observable(); // This computed calculates which products from your data // meet the requirements whenever one of the selections changes this.selectedProducts = ko.pureComputed(function() { return products.filter(function(product) { return product.category === this.selectedCategory() && product.country === this.selectedCountry(); }.bind(this)); }, this); // Here, we create a list of countries that appear in your data, // this list is used to fill the dropdown's options this.countries = getKeyUniques(products, "country"); // Do the same for categories this.categories = getKeyUniques(products, "category"); }; ko.applyBindings(new ViewModel()); // Utils function getKeyUniques(arr, key) { return Object.keys(arr.reduce(function(map, item) { map[item[key]] = true; return map }, {})); }; 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <select data-bind="options: countries, value: selectedCountry"></select> <select data-bind="options: categories, value: selectedCategory"></select> <ul data-bind="foreach: selectedProducts"> <li data-bind="text: name"></li> </ul> 



Answer 2:

我的解决方案如下。 我想基于ID进行过滤。 计划从服务器获取国家和类别的清单,然后从服务器接收的产品的过滤列表。 一个巨大的感谢你给用户。 在您的帮助,并与网站上的例子来http://knockoutjs.com/examples/cartEditor.html我解决我的问题。 张贴在这里我的解决方案:

 var countries = [ { "id": 1, "name": "Russia" }, { "id": 2, "name": "USA" }, { "id": 3, "name": "Great Britain" } ]; var categories = [ { "id": 1, "name": "Classic Cars" }, { "id": 2, "name": "Motorcycles" }, { "id": 3, "name": "Planes" } ]; var products = [ { "name": "P-51-D Mustang", "countryId": 2, "categoryId": 3, "price": 12.42 }, { "name": "1997 BMW R 1100 S", "countryId": 2, "categoryId": 2, "price": 60.87 }, { "name": "2002 Chevy Corvette", "countryId": 2, "categoryId": 1, "price": 100.87 }, { "name": "1998 Chrysler Plymouth Prowler", "countryId": 1, "categoryId": 1, "price": 150.87 } ]; var CartLine = function () { var self = this; self.countries = ko.observableArray(countries); self.categories = ko.observableArray(categories); self.quantity = ko.observable(1); self.selectedCountry = ko.observable(); self.selectedCategory = ko.observable(); self.selectedProduct = ko.observable(); self.subtotal = ko.pureComputed(function () { return self.selectedProduct() ? (self.selectedProduct().price * self.quantity()) : "yet"; }); self.products = ko.pureComputed(function () { return $.grep(products, function (item) { return (self.selectedCountry() && self.selectedCategory() && item.countryId === self.selectedCountry().id && item.categoryId === self.selectedCategory().id); }); }); }; var Cart = function () { var self = this; self.lines = ko.observableArray([new CartLine()]); self.lines2 = ko.observableArray([new CartLine()]); self.grandTotal = ko.pureComputed(function () { var total = 0; $.each(self.lines(), function () { total += this.subtotal(); }); return total; }); // Operations self.addLine = function () { self.lines.push(new CartLine()); }; self.removeLine = function (line) { self.lines.remove(line); }; }; ko.applyBindings(new Cart()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="stl.css" /> </head> <body> <div class='liveExample'> <table width='50%'> <thead> <tr> <th width='25%'>Country</th> <th width='25%'>Category</th> <th class='price' width='15%'>Product</th> <th class='price' width='15%'>Price</th> <th class='quantity' width='10%'>Quantity</th> <th class='price' width='15%'>Subtotal</th> <th width='10%'></th> </tr> </thead> <tbody data-bind='foreach: lines'> <tr> <td> <select data-bind='options: countries, optionsText: "name", optionsCaption: "Select...", value: selectedCountry'> </select> </td> <td> <select data-bind='options: categories, optionsText: "name", optionsCaption: "Select...", value: selectedCategory'> </select> </td> <td> <select data-bind='visible: (selectedCountry() && selectedCategory()), options: products, optionsText: "name", optionsCaption: "Select...", value: selectedProduct'> </select> </td> <td> <span data-bind='text: selectedProduct() ? selectedProduct().price : 0'> </span> </td> <td class='quantity'> <input data-bind='value: quantity, valueUpdate: "afterkeydown"' /> </td> <td class='price'> <span data-bind='text: subtotal()'> </span> </td> <td> <a href='#' data-bind='click: $root.removeLine'>Remove</a> </td> </tr> </tbody> </table> <p class='grandTotal'> Total value: <span data-bind='text: grandTotal()'> </span> </p> <button data-bind='click: addLine'>Add product</button> </div> <script src="knockout-3.4.1.js" type="text/javascript"></script> <script src="jquery-3.1.1.min.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> </body> </html> 



Answer 3:

我做了什么,你问基于下面的方法 -

  • 保持在下拉菜单中为类别和选定的值的轨道countryfiltering出的车辆阵列的基础上countryIdcategoryId

对于这一点,我已经subscribed到的选定值countrycategory ,所以当其中一方的变化,我所说的过滤器,这样它在第三个下拉菜单更新更新所选车辆。

它也包括在视图模型定义的末尾一些测试结果。

PS - 请把我的数据的糟糕的组合,但我想我的努力就足以让你得到它的要点;-)

这里是小提琴



文章来源: Knockout three cascading dropdowns