【问题标题】:Dropdown in kendo UI grid剑道 UI 网格中的下拉菜单
【发布时间】:2014-09-23 00:22:17
【问题描述】:

我需要一个 Kendo-UI 网格的下拉菜单,并遇到了以下示例: http://codepen.io/jordanilchev/pen/cnkih?editors=001

但是在这个例子中,下拉菜单的键和显示文本也都包含在网格的数据源中,这看起来很多余。我在 Telerik 的网站上查看了一个类似的例子,那里也是一样的。

这里是类型下拉菜单的数据源:

var types = [
    {
        "Type": "FB",
        "Name": "Facebook"
    },
    {
        "Type": "TW",
        "Name": "Twitter"
    },
    {
        "Type": "YT",
        "Name": "YouTube"
    },
    {
        "Type": "PI",
        "Name": "Pinterest"
    }
];

到目前为止一切顺利。但这里是实际网格的数据 - 请注意它还包含每条记录的类型和名称:

var products = [{
   "ProductID": 1,
   "ProductName": "Chai",
   "Type": {
      "Type": "FB",
      "Name": "Facebook"
   }
}, {
   "ProductID": 2,
   "ProductName": "Chang",
   "Type": {
      "Type": "FB",
      "Name": "Facebook"
   }
}...

我的预期是只有类型必须在网格的数据源中 - 像这样:

var products = [{
   "ProductID": 1,
   "ProductName": "Chai",
   "Type": "FB",
}, {
   "ProductID": 2,
   "ProductName": "Chang",
   "Type": "FB",
}...

有没有一种方法可以在 Kendo UI 网格中使用下拉菜单,而不必为网格数据源中的每条记录同时包含键和显示文本?换句话说,网格会知道引用下拉列表的数据源来获取单元格的显示文本。

2014 年 9 月 23 日更新: 当下拉列表的数据源是硬编码/本地数组时,CodingWithSpike 提出的解决方案可以正常工作,但是在从服务器加载下拉列表的数据时,我很难让它工作。问题似乎是在读取下拉列表的数据源之前网格已初始化。

为了“模拟”一个 $http 调用来填充数据源,我使用了 setTimeout:

$(document).ready(function () {
  var categories = [];

  setTimeout(function() {
    categories = [{
      "value": 1,
      "text": "Beverages"
    },{
      "value": 2,
      "text": "Condiments"
    },{
      "value": 3,
      "text": "Confections"
    }];
    $('#grid').data('kendoGrid').dataSource.read(); // Just as a test, but not even this helps
    $('#grid').data('kendoGrid').refresh(); // Just as a test, but not even this helps
  }, 1000);

当数据按上述方式(或通过 $http)加载时,下拉字段现在包含值 (id) 而不是文本。这是一个显示这一点的 plunker: http://plnkr.co/edit/DWaaHGVAS6YuDcqTXPL8?p=preview

请注意,真正的应用程序是 AngularJs 应用程序,我宁愿不使用一些 jQuery hack 等到下拉数据可用然后创建网格元素。

如何处理来自服务器的数据?

【问题讨论】:

    标签: javascript kendo-ui telerik


    【解决方案1】:

    查看“外键”列的剑道演示。我认为这正是您想要的。

    http://demos.telerik.com/kendo-ui/grid/foreignkeycolumn

    他们使用类别列表:

               var categories = [{
                    "value": 1,
                    "text": "Beverages"
                },{
                    "value": 2,
                    "text": "Condiments"
                },{
                    "value": 3,
                    "text": "Confections"
                },{
                    "value": 4,
                    "text": "Dairy Products"
                },{
                    "value": 5,
                    "text": "Grains/Cereals"
                },{
                    "value": 6,
                    "text": "Meat/Poultry"
                },{
                    "value": 7,
                    "text": "Produce"
                },{
                    "value": 8,
                    "text": "Seafood"
                }];
    

    该演示有点欺骗性,因为他们的网格数据包含整个“类别”:

    var products = [{
        ProductID : 1,
        ProductName : "Chai",
        SupplierID : 1,
        CategoryID : 1,
        QuantityPerUnit : "10 boxes x 20 bags",
        UnitPrice : 18.0000,
        UnitsInStock : 39,
        UnitsOnOrder : 0,
        ReorderLevel : 10,
        Discontinued : false,
        Category : {
            CategoryID : 1,
            CategoryName : "Beverages",
            Description : "Soft drinks, coffees, teas, beers, and ales"
        }
    }
    

    但是,如果您查看列定义:

    { field: "CategoryID", width: "200px", values: categories, title: "Category" },
    

    指定的字段是CategoryID 而不是Category,因此网格数据项实际上根本不需要指定“类别”属性,可以是:

    var products = [{
        ProductID : 1,
        ProductName : "Chai",
        SupplierID : 1,
        CategoryID : 1,  // <-- this is the important part!
        QuantityPerUnit : "10 boxes x 20 bags",
        UnitPrice : 18.0000,
        UnitsInStock : 39,
        UnitsOnOrder : 0,
        ReorderLevel : 10,
        Discontinued : false
    }
    

    我怀疑“类别”在其中只是因为此 JSON 文件由几个示例共享,因此可能需要其他示例。


    更新

    关于在“类别”(或其他)FK 表之前加载网格的问题:

    在网格数据源上使用延迟或回调来等待 FK 数据源完成加载,然后再填充网格数据。或者,您可以初始化网格,但将其设置为 autoBind: false,这样它实际上不会立即从其 DataSource 中读取。

    类似这样的东西(抱歉有任何错误,这是我脑子里乱写的):

    (function () {
        // for the foreign keys
        var categoriesDataSource = new kendo.data.DataSource({
            transport: {
                read: {
                    url: "http://somewhere.com/categories"
                }
            }
        });
    
        // for the actual grid data
        var gridDataSource = new kendo.data.DataSource({
            ...
        });
    
        // init the grid widget
        var gridWidget = $("#grid").kendoGrid({
            dataSource: gridDataSource,
            autoBind: false, // <-- don't read the DataSource. We will read it ourselves.
            columns: [ ... ]
        });
    
        // now we can read the FK table data.
        // when that completes, read the grid data.
        categoriesDataSource.fetch(function () {
            gridDataSource.fetch();
        });
    });
    

    【讨论】:

    • 这是有道理的(并且似乎有效),但我有一个问题:它如何知道哪个字段用于值并显示下拉文本?是否按照惯例,下拉数据源中必须有一个名为“value”的字段和一个名为“text”的字段?这是我测试您的解决方案的一个 plunker:plnkr.co/edit/DWaaHGVAS6YuDcqTXPL8?p=preview
    • 是的,valuetext 按惯例使用。我不确定是否有办法改变这一点,而无需通过剑道源进行筛选。
    • 我尝试实施您的解决方案,但在从服务器加载下拉数据时遇到问题。我已经编辑了我的问题以包含更多数据。也许你可以再传授一些你的智慧?
    • 我尝试使用 autoBind=false,然后确保在调用 dataSource.read() 之前已填充下拉数组(根据文档将绑定网格),但它仍然没有工作。很奇怪 - 不知道我错过了什么。这是一个更新的 plunker:plnkr.co/edit/ZjuK9wk3Zq80yA0LIIWg?p=preview 您能否更新 plunker 以展示您的解决方案?
    • 有趣的是,Kendo 似乎不喜欢在网格初始化后换掉categories。我现在没有我面前的网格源来尝试进一步调查原因。如果您的应用程序允许,您可能希望等到加载类别数据后再初始化网格。
    【解决方案2】:

    我向 Telerik 询问了这个问题,这是他们给出的解决方案。

    当下拉列表的数据可用时,在网格上使用 setOptions,如下所示(再次,为了简单起见,我在这里使用 setTimeout 而不是 Ajax 调用):

    setTimeout(function() {
      categories = [{
          "value": 1,
          "text": "Beverages"
      },{
          "value": 2,
          "text": "Condiments"
      },{
          "value": 3,
          "text": "Confections"
      }];
      var grid = $('#grid').data('kendoGrid');
      var cols = grid.columns;
      cols[1].values = categories;
      grid.setOptions({columns: cols}); 
      $('#grid').data('kendoGrid').refresh();
    }, 200);
    

    另外,不需要 autoBind: false。

    这是一个更新的 plunker: http://plnkr.co/edit/ZjuK9wk3Zq80yA0LIIWg?p=preview

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      相关资源
      最近更新 更多