剑道UI网格中的下拉菜单



我需要一个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"
   }
}...

我所期望的是,只有Type必须在网格的数据源中——就像这样:

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破解,等到下拉数据可用后再创建网格元素。

如何使用来自服务器的数据进行此操作?

看看"外键"列的Kendo演示。我想这正是你想要的。

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();
    });
});

我向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

最新更新