2013-04-25 32 views
0

我有以下的代码,构建一个剑道UI格:如何使用服务器端分页将数据加载到Kendo UI Grid?

// build grid columns 

    // the check box column is always visible for all users 
    var columns = [{ 
     field:'<input id="masterCheck" class="check" type="checkbox" /><label for="masterCheck"></label>', 
     template: '<input class="check rowSelect" id="${id}" type="checkbox" /><label for="${id}"></label>', 
     filterable: false, 
     width: 33, 
     sortable: false // may want to make this sortable later. will need to build a custom sorter. 
    }]; 

    // build the rest of the columns using data provided by the server 
    var metrics = initialData.metric; 
    for (var i=0; i < metrics.length; i++) { 
     var metric = metrics[i]; 
     var column = {}; 
     column.field = metric.qualifiedName; 
     column.title = metric.label; 
     column.width = metric.colWidth; 
     // initially hide all columns. we'll know exactly which ones to show after a search 
     column.hidden = true;   
     column.type = metric.type; 

     // handle special considerations 
     if (column.type === 'float' || column.type === 'int') {   

      // format all floats to two decimal places 
      if (column.type === 'float') { 
       column.format = '{0:n2}'; 
      } 
      // the grid only has a type of number.    

      column.attributes = {'class' : 'right-align'}; 

      var field = column.field; 

      // create a closure to build a function that captures the field variable value 
      // in this iteration. Immediately execute the anonymous outer function so 
      // that the inner function is returned as assignment to the footerTemplate 
      // variable. The param data will be passed to the function by the grid. 
      // That function then executes the buildFooter which has the right field value 
      // due to the closure. notice that each invocation of the outer function 
      // creates a new scope chain that adds a new inner function. 
      column.footerTemplate = (function(field, columnType) {return function() { return buildFooter(field, columnType); }; })(field, metric.type); 
      column.type = 'number'; 

     } else if (column.type === 'date') { 
      column.format = '{0:yyyy-MM-dd}'; 
     } else if (column.field === 'attachments') { 
      //column.field = 'text'; 
      // use a template defined in search.jsp to style this complex 
      // object 
      column.template = kendo.template($('#attachmentTemplate').html()); 
      column.sortable = false; 
      column.filterable = false; 
     } else if (column.type === 'list') { 
      column.type = 'string'; 
     } 

     columns.push(column);   
    } 

    var toolbarItems = [{ name: 'custom', text: 'Filter', className: 'filterClass k-state-disabled', imageClass: 'k-icon k-i-funnel'}, 
         { name: 'view', text: 'View', className: 'viewClass k-state-disabled', imageClass: 'k-icon k-i-search' }]; 
    // only show build the edit and delete buttons in the toolbar if the 
    // user has permissions 
    if ($('#hasAdminControls')[0]) { 
     toolbarItems.push({ name: 'edit', text: 'Edit', className: 'editClass k-state-disabled' }); 
     toolbarItems.push({ name: 'destroy', text: 'Delete', className: 'deleteClass k-state-disabled' }); 
    } 

    var options = { 

     autoBind: false, 
     dataBound: function() { 

      alert('dataBound'); 
      for(var i =0; i < checkedRows.length; i++){ 
       $('#'+ checkedRows[i]).attr('checked','checked'); 
      }    
      $('.rowSelect').click(setGridControlsState); 
      setGridControlsState(); 

      $('.k-grid-content').removeHighlight(); 
      $('.k-grid-content').highlight(uniqueHighlights); 
     },  
     dataSource: { 
      //type: 'json', 
      //batch: 'true', 
      serverPaging: true, // we may need to use paging for performance reasons 
      //schema: { 
      // total: 'total'//function(response) { console.log(response); alert('hi2'); return 500; } 
      //}, 
      //schema: { 
       //model: Acquisition // if we use a model then complex objects' fields all have string type 

      pageSize: 10, 

      //serverFiltering: true, // we may want to use this in the future if client filtering becomes a performance issue 
      //serverSorting: true, // we may want to use this in the future if client sorting becomes a performance issue 
      transport: { read: 
      function(options) { 

       var setupOptions = { 
         success: function(data, statusText, xhr, $form) {options.success(data); loadSearch(data, statusText, xhr, $form)}, 
         type: 'POST', 
         dataType: 'json', 
         data: {skip: options.data.skip, take: options.data.take}, 
         url: '../search.x', 
         error: errorHandler.handle, 
         timeout: 50000 
       }; 
       $('#searchForm').ajaxSubmit(setupOptions); 
      } 

      } 
     }, 
     height: 600, 
     pageable: { 
      //numeric: false, 
      //previousNext: false, 
      messages: { 
       display: "{2} Acquisitions" 
      }, 
      pageSizes: true 
     }, 
     sortable: true, 
     resizable: true, 
     filterable: true, 
     toolbar: toolbarItems, 
     columns: columns 
    }; 

    // create the grid using the above options 
    $('#resultsGrid').kendoGrid(options); 

    // for purely aesthetic purposes, move the toolbar to the bottom (by default it's at the top) 
    $('#resultsArea').find('.k-grid-toolbar').insertAfter($('#resultsArea .k-grid-footer')); 
    var grid = $('#resultsGrid').data('kendoGrid'); 
    grid.refresh(); 

网格最初是隐藏的,但搜索表单提交后显示。当搜索表单提交,执行以下功能:

function startSearch(evt) { 
    evt.preventDefault(); 

    showLoadingGrid(); 
    var grid = $('#resultsGrid').data('kendoGrid'); 
    grid.dataSource.read(); 

} 

的grid.dataSource.read()函数调用将导致AJAX调用由transport.read发起的服务器。但是,成功函数永远不会被调用,因为kendo会抛出错误。它声明d.oneOfMyObjects是未定义的kendo.web.min.js(第9行)。当我查看json响应时,我有几个来自服务器的json对象。其中一个对象是一组对象。每个对象都有一个属性(这是一个对象),称为oneOfMyObjects。每个oneOfMyObjects是非空的。所以,我不确定为什么剑道失败。我正在使用kendoui.2012.3.1315。我怎样才能停止kendo抛出这个错误,并允许我的loadSearch回调函数被调用?

2nd编辑 错误发生在options.success(data)成功函数中;

编辑 编辑问题以包含来自服务器的输出。请注意,相同的输出作品,未经服务器分页细(也不得不修改数据安全的目的输出......我试图保持相同的结构虽然但我希望我没有意外更改,使其不符合JSON):

{ 
    "total":500, 
    "displayFields":["summary","page","take","pageSize","skip"], 
    "object":[{ 
     "id":16835, 
     "date":-2208967200000, 
     "type":"Needs Value", 
     "nestedObject1":{ 
      "id":16870, 
      "name":"Not Specified", 
      "region":{ 
       "name":"Needs Value" 
      } 
     }, 
     "oneOfMyObjects":{ 
      "id":16923, 
      "name":"Needs Value" 
     } 
    }, { 
     "id":16836, 
     "date":-2208967200000, 
     "type":"Needs Value", 
     "nestedObject1":{ 
      "id":16873, 
      "name":"Not Specified", 
      "region":{ 
       "name":"Needs Value" 
      } 
     }, 
     "oneOfMyObjects":{ 
      "id":16925, 
      "name":"Needs Value" 
     } 
    }, /* 8 more records */] 
} 

3日编辑包括loadSearch功能

function loadSearch(data, statusText, xhr, $form, options) { 

    if (data.validationError) { 
     // TODO we need to look at the message from the reply 
     // right now though only date validation errors will exist 
     dialog.show('Error', 'Please enter dates formatted as yyyy-mm-dd.'); 
     global.loadingIndicator.hide(); 
     return; 
    } 

    checkedRows = []; 
    var object= data.object; 

    var grid = $('#resultsGrid').data('kendoGrid'); 

    // clear any filters. This also help with an issue where no 
    // rows are shown due to a filter. 
    grid.dataSource.filter({}); 


    // set the search results data in the grid 
    grid.dataSource.data(object); 

    // show columns that are either a user preference 
    // column (or default set if user has no preferences) 
    // or a field matching search data 

    // let's only hide/show the delta between 
    // previously viewed cols and new cols to display 
    // since it's much faster than hiding all old 
    // and then displaying all new cols 
    var oldCols = $('#displayColumns').val() || []; 

    // the server tells the UI which fields to display 
    // based on user preference and fields that that 
    // have matching search data 
    var newCols = data.displayFields; 

    var removedCols = oldCols.diff(newCols); 
    for (var i in removedCols) { 
     $('#displayColumns option[value="' + removedCols[i] + '"]').removeAttr('selected'); 
     grid.hideColumn(removedCols[i]); 
    } 

    var addedCols = newCols.diff(oldCols); 
    for (var i in addedCols) { 
     grid.showColumn(addedCols[i]); 
     $('#displayColumns option[value="' + addedCols[i] + '"]').attr('selected', 'selected'); 
    } 

    // we have to tell the chosen overlay that we updated the list 
    $('#displayColumns').trigger('liszt:updated'); 

    // we have to keep track of the current selected values 
    // so that when the user changes to selection we'll 
    // be able to compare to the original selection 
    // and now what they changed. 
    $('#displayColumns').data('chosen-values', $('#displayColumns').val()); 


    // display the results 
    grid.refresh(); 

    realignFooter(); 

    // Highlight search matches so the user can easily see 
    // why the record is in the result grid. 
    // Unfortunately, the highlights library takes a comma-delimited list. 
    // It's problematic when the search results contain a comma. 


    // remove previous highlights 
    //$('.k-grid-content').removeHighlight(); 

    uniqueHighlights = data.uniqueHighlights || []; 
    $('.k-grid-content').removeHighlight(); 
    $('.k-grid-content').highlight(uniqueHighlights); 

    // reset the controls since all checkboxes have been cleared 
    setGridControlsState(); 

    // register event to capture clicks on grid checkboxes 
    // we can't do this during initialization b/c the checkboxes 
    // are not yet built. Note: we don't have to remove 
    // the events associated with previous checkboxes as 
    // jquery should automatically do this. 
    $('.rowSelect').click(setGridControlsState); 

    // remove loading indicator 
    global.loadingIndicator.hide(); 

    // style the UI to give the user an option to save the columns again 
    $('#saveCols > span').empty().text('Save Columns'); 
    $('#saveCols').removeClass('k-state-disabled'); 

} 
+0

您是否介意在OP中包含响应的示例? – OnaBai 2013-04-25 21:48:59

+0

你从哪里得到'transport.read'有一个'success'选项?我在文档中找不到它... – OnaBai 2013-04-25 21:52:27

+0

你说得对。这就解释了为什么loadSearch从未被调用。但我需要调用一个成功函数。所以,我编辑了我的问题,使transport.read指向一个函数。该函数中的AJAX调用是通过[Malsup表单插件](http://malsup.com/jquery/form/)。 – James 2013-04-26 14:32:17

回答

1

您还没有schema指定在哪里可以找到数据。你需要说些什么,如:

schema : { 
    data : "object", 
    total: "total" 
} 

事实上,你不说在哪里可以找到结果使得不可能显示任何字段。

关于成功函数永远不会被称为,这样的选项不存在(AFAIK)。

+0

Thanks OnaBai。这确实可以防止我看到的错误。但是,总没有被设置。所以,客户端UI认为只有一页数据存在。如何才能正确设置?另外,请你看看我的最新编辑?我不得不改变transport.read指向一个函数,因为我需要一个成功的函数,并且想使用Malsup表单插件。 – James 2013-04-26 14:51:40

+0

对不起,但我实际上仍然收到一个错误,将schema.data设置为对象。错误发生在options.success(data)错误是TypeError:e.indexOf不是函数(kendo.web.min.js(第9行))。我可以删除那个电话并且错误消失,但总没有被设置。 – James 2013-04-26 15:06:20

0

我只是把这个作为一个评论来澄清什么对你有用,但它会更难看到代码,所以我会开始这个,看看我能否完全回答你的问题。

transport: { 
    read: { 
     url: '@Url.Action("_List", "Check")', 
     data: gridParams, 
     type: 'POST' 
    }, 
function gridParams() { 
     return { 
      Field1: $('#fd1').val(), 
      Field2: $('#fd2').val(), 
      Field3: $('#fd3').val() 
     }; 
    } 

fd1-3将作为您的搜索表单ID是它的字段,您需要将参数传递给您的控制器。

然后为你的控制器动作,

[HttpPost] 
    public JsonResult _List(string Field1, DateTime? Field2, DateTime? Field3, int skip, int take) 
    { 

然后你只想用这些参数来改变你的db.TableName.Where(W => w.fd1 ==字段1 & & w.fd2 ==字段2 || w.fd3 ==字段3).Skip(跳过)

等等等等等等。

+0

感谢您的回复。我有一种方法来获取表单数据,而不必使用[Malsup表单插件](http://malsup.com/jquery/form/)显式获取值。我已经对原始问题进行了编辑,以说明我是如何执行此操作的。我试图将读取设置为一个对象来通过错误,但我真的需要将它设置为一个函数,因为我想使用表单插件。请参阅上述修改。对不起,这个改变。 – James 2013-04-26 14:48:37

0
var dataSource = new kendo.data.DataSource({ 
     serverPaging: true, 
     serverSorting: true, 
     pageSize : 15, 
     transport : { 
     read : { 
      url : getEmployeeData, 
      dataType : "json" 
     }, 
     parameterMap : function(options, operation) { 
      if (operation == "read") { 
       return { 
        page: dataSource._page, 
        pageSize: dataSource._pageSize 
      }; 
     } 
     } 
    }, 
    batch : true, 
    schema : { 
     data: "data", 
     total: "total", 
     model : { 
     id : "id", 
     fields : { 
      name : { 
      validation : { 
       required : true 
      } 
      } 
     } 
     } 
    } 
    }); 
相关问题