首页 > 解决方案 > 剑道层次网格 - 层次结构不起作用

问题描述

我正在尝试在 mvvm 中创建一个分层网格,经历了多个示例,但没有运气。一定是做错了什么。虽然它没有给出任何异常,但层次结构不起作用,正常网格正在填充。

我的虚拟机如下:

var PolicyList;
xxx.PayRollProcess.PayRollPolicy = (function ($, kendo, _, App) {

  var vmSalaryPolicy = kendo.observable({
    // Properties
    //*******************************
    Id: null,
    Name: null,
    Description: null,
    CreatedBy: null,
    CreatedDate: null,
    PolicyID: null,
    SaveFieldButtonText: "Save Field",
    PolicyList : new kendo.data.DataSource({
      transport: {
        read: {
          type: "GET",
          url: xxx.Layout.viewModel.GetApiUrl("PayRoll/GetPolicies"),
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          complete: function (data) {
            debugger;
            if (data.responseJSON !== null) {
              vmSalaryPolicy.set("IsRecordFound", data.responseJSON.length > 0 ? true : false);
              vmSalaryPolicy.set("SalryField", data.responseJSON[0]);
            }
          },
          error: function (err) {
            xxx.Layout.viewModel.ShowError(err);
          }
        }
      },
      schema: {
        model: {
          fields: {
            SalaryPolicyID: { type: "number" },
            Name: { type: "string" },
            Description: { type: "string" },
            CreatedBy: { type: "bool" },
            CreatedOn: { type: "string" }
          }
        }
      },
      pageSize: 10
    }),
    AllPolicyFieldDetailList : new kendo.data.DataSource({
      transport: {
        read: {
          type: "GET",
          url: xxx.Layout.viewModel.GetApiUrl("PayRoll/GetAllPayRollPolicyDetails"),
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          complete: function (data) {
            if (data.responseJSON !== null) {
              vmSalaryField.set("IsRecordFound", data.responseJSON.length > 0 ? true : false);
              vmSalaryField.set("SalryField", data.responseJSON[0]);
            }
          },
          error: function (err) {
            xxx.Layout.viewModel.ShowError(err);
          }
        }
      },
      schema: {
        model: {
          fields: {
            SalaryPolicyID: { type: "number" },
            SalaryPolicyName: { type: "bool" },
            SalaryPolicyDescription: { type: "string" },
            SalaryFieldID: { type: "string" },
            SalaryFieldName: { type: "bool" },
            Type: { type: "bool" },
            HeaderName: { type: "string" }
          }
        }
      },
      pageSize: 10
    }),
    dataSource: PolicyList,
    detailInit: function (e) {
      debugger;
      $("<div/>").appendTo(e.detailCell).kendoGrid({
        dataSource: {
          type: "Get",
          transport: {
            read: {
              type: "GET",
              url: xxx.Layout.viewModel.GetApiUrl("PayRoll/GetAllPayRollPolicyDetails"),
              contentType: "application/json; charset=utf-8",
              dataType: "json",
              complete: function (data) {
                if (data.responseJSON !== null) {
                  vmSalaryPolicy.set("IsRecordFound", data.responseJSON.length > 0 ? true : false);
                  vmSalaryPolicy.set("SalryField", data.responseJSON[0]);
                }
              },
              error: function (err) {
                xxx.Layout.viewModel.ShowError(err);
              }
            }
          },
          serverPaging: true,
          serverSorting: true,
          serverFiltering: true,
          pageSize: 6,
          filter: { field: "SalaryPolicyID", operator: "eq", value: e.data.SalaryPolicyID }
        },
        scrollable: false,
        sortable: true,
        pageable: true,
        columns: [
          { field: "SalaryFieldID", title: "ID", width: "110px" },
          { field: "SalaryFieldName", title: "Field Name", width: "110px" },
          { field: "Type", title: "Type" },
          { field: "HeaderName", title: "Header Name", width: "300px" }
        ]
      });
    },
    dataBound: function (e) {
      debugger;
      e.sender.expandRow(e.sender.tbody.find("tr.k-master-row").first());
    },
  });

  $(function () {
    kendo.bind($("#PolicyPage"), vmSalaryPolicy);
  });
  return { viewModel: vmSalaryPolicy };
})(jQuery, kendo, _, xxx);

.cshtml 包含:

<div class="box-body rm-padding">
  <div data-bind="invisible: IsRecordFound">No Policy Details found.</div>
  <div id="PayRollPolicyFieldGrid"
       data-role="grid"
       data-sortable="true"
       data-pageable="true"
       data-height="450"
       data-detail-init="detailInit"
       data-columns='[{"field": "SalaryPolicyID"}, {"field": "Name"}, {"field": "Description"}, {"field": "CreatedBy"}, {"field": "CreatedOn"}]'
       data-bind="source: PolicyList, events: { dataBound: dataBound }">
  </div>

</div>

我在这里尝试了这个例子

但没有运气。

它仅加载带有策略详细信息的网格。

GetPolicies 的 JSON:

{
  "ArrayOfSalaryPolicy": {
  "SalaryPolicy": {
    "CreatedBy": "101429",
      "CreatedOn": "2019-01-18T21:01:21.97",
      "Description": "Band A Salary Policy",
      "Name": "Band-A",
      "SalaryPolicyID": "1"
  },
  "_xmlns:i": "http://www.w3.org/2001/XMLSchema-instance",
    "_xmlns": "http://schemas.datacontract.org/2004/07/xxx.Common"
}
}

AllPolicyFieldDetailList 的 JSON:

{
  "ArrayOfSalaryPolicyField": {
  "SalaryPolicyField": [
    {

      "HeaderID": "0",
      "HeaderName": "OtherDeduction",
      "ID": "5",
      "IsActive": "false",
      "SalaryFieldID": "0",
      "SalaryFieldName": "LWF",
      "SalaryPolicyDescription": "Band A Salary Policy",
      "SalaryPolicyID": "1",
      "SalaryPolicyName": "Band-A",
      "Type": "Deduction"
    },
    {

      "HeaderID": "0",
      "HeaderName": "StatutoryDeduction",
      "ID": "3",
      "IsActive": "false",
      "SalaryFieldID": "0",
      "SalaryFieldName": "PF",
      "SalaryPolicyDescription": "Band A Salary Policy",
      "SalaryPolicyID": "1",
      "SalaryPolicyName": "Band-A",
      "Type": "Deduction"
    },
    {

      "HeaderID": "0",
      "HeaderName": "StatutoryDeduction",
      "ID": "4",
      "IsActive": "false",
      "SalaryFieldID": "0",
      "SalaryFieldName": "TDS",
      "SalaryPolicyDescription": "Band A Salary Policy",
      "SalaryPolicyID": "1",
      "SalaryPolicyName": "Band-A",
      "Type": "Deduction"
    },
    {

      "HeaderID": "0",
      "HeaderName": "Other Allwances",
      "ID": "2",
      "IsActive": "false",
      "SalaryFieldID": "0",
      "SalaryFieldName": "Conveyance",
      "SalaryPolicyDescription": "Band A Salary Policy",
      "SalaryPolicyID": "1",
      "SalaryPolicyName": "Band-A",
      "Type": "Earning"
    },
    {

      "HeaderID": "0",
      "HeaderName": "Earnings",
      "ID": "1",
      "IsActive": "false",
      "SalaryFieldID": "0",
      "SalaryFieldName": "HRA",
      "SalaryPolicyDescription": "Band A Salary Policy",
      "SalaryPolicyID": "1",
      "SalaryPolicyName": "Band-A",
      "Type": "Earning"
    }
  ],
    "_xmlns:i": "http://www.w3.org/2001/XMLSchema-instance",
    "_xmlns": "http://schemas.datacontract.org/2004/07/xxx.Common"
}}

我在运行时比较了我的代码提供的示例,一个有趣的发现是,在示例中,它加载了“k-master-row”类,<tr>但在我的情况下它没有。

代码运行时没有任何异常,它会加载策略。但它不显示层次结构网格。我已将“调试器”放在 dataInit 中,但它永远不会去那里或停止。

标签: c#mvvmkendo-ui

解决方案


我设法使主从网格使用 MVVM 工作的唯一方法是为详细信息行提供一个模板(即使它只是一个“空”的模板,您稍后会在detailInit活动期间对其进行操作)。

另请注意,在 MVVM 小部件初始化期间,上下文是窗口,因此当您的data-detail-init属性被解析时,kendo 将在错误的位置查找。您应该将其移至 binding/events 属性,因为设置绑定时,上下文就是您要绑定的可观察对象。我已经修改了你的标记来证明这一点。

<script id="grid-detail-placeholder" type="text/x-kendo-template"></script>

<div class="box-body rm-padding">
  <div data-bind="invisible: IsRecordFound">No Policy Details found.</div>
  <div id="PayRollPolicyFieldGrid"
       data-role="grid"
       data-sortable="true"
       data-pageable="true"
       data-height="450"
       data-detail-template="grid-detail-placeholder"
       data-columns='[{"field": "SalaryPolicyID"}, {"field": "Name"}, {"field": "Description"}, {"field": "CreatedBy"}, {"field": "CreatedOn"}]'
       data-bind="source: PolicyList, events: { detailInit: detailInit, dataBound: dataBound }">
  </div>

</div>

推荐阅读