【问题标题】:Need to get custom checkbox columns to work in KoGrid需要让自定义复选框列在 KoGrid 中工作
【发布时间】:2017-09-10 06:56:48
【问题描述】:

我正在尝试显示一个包含一些基本显示数据的 KoGrid。该网格有一个嵌入的复选框,用于说明该节目是否为电影,另一个嵌入的复选框用于说明该节目是否为卡通片。下面提供了该网格的 Javascript,在一个名为 testgrid.js 的文件中:

var theList = [
               { isMovie: false, isCartoon: true, name: "Johnny Quest" },
               { isMovie: true, isCartoon: true, name: "Heavy Metal" },
               { isMovie: true, isCartoon: false, name: "Star Wars Rogue One" },
               { isMovie: false, isCartoon: false, name: "The Invaders" },
               { isMovie: true, isCartoon: false, name: "Star Trek: The Voyage Home" },
               { isMovie: false, isCartoon: true, name: "Space Ghost" },
               { isMovie: false, isCartoon: false, name: "Star Trek Classic" },
               { isMovie: false, isCartoon: false, name: "Lost In Space" },
               { isMovie: false, isCartoon: true, name: "Bugs Bunny/Road Runner Hour" },
           ];

var showTitles = [
              {field: 'isMovie',displayName: 'Movie',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: theData.isMovie' />"},
              {field: 'isCartoon',displayName: 'Cartoon',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: theData.isCartoon' />"},
              {field: 'name',displayName: 'Show Name',width: '78%'},
          ];

var TestModel = function() {
  var self = this;

  self.theData = ko.observableArray(theList);
  self.selectShow = ko.observableArray([]);

  self.instantiateSelf = function() {
       ko.applyBindings(theModel);
   }

  self.listOptions = {
      afterSelectionChange: function () { alert("Show Selected: "+selectShow()[0]); },
      data: self.theData,
      selectedItems: self.selectShow,
      displaySelectionCheckbox: false,
      multiSelect: false,
      columnDefs: showTitles
  }
}
var theModel = new TestModel();

下面提供了我使用的 HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
   <title>Grid Test</title>
   <link href="lstyles.css" rel="stylesheet" type="text/css">
   <link href="KoGrid.css" rel="stylesheet" type="text/css">
   <script src="knockout-3.4.2.js" type="text/javascript"></script>
   <script src="jquery-3.2.0.js" type="text/javascript"></script>
   <script src="koGrid-2.1.1.js" type="text/javascript"></script>
   <script src="jquery-ui.min.js" type="text/javascript"></script>
   <script type="text/javascript">
      $(document).ready(function() {
         jQuery.support.cors = true;
         theModel.instantiateSelf();
      });
   </script>
 </head>
<body>
  <div id="body">
     <div id="data">
        <div id="display">
          <div id="lstStyle" data-bind="koGrid: listOptions"></div>
        </div>
        <div id="footer">
        </div>
    </div>
  </div>
 <script>
 </script>
</div>  
   <script src="testgrid.js" type="text/javascript"></script>
</body>
</html>

网格不显示。显示的内容看起来像是网格显示的一部分,但没有出现。

我做了一些故障排除。我发现问题在于我为 testgrid.js 中的 showTitles 对象中的复选框提供的 cellTemplate 定义中的“数据绑定”语句。如果我删除这些语句,网格会显示,但我无法选中或取消选中复选框,也无法获取复选框的状态。

有没有办法让这些复选框在 kogrid 中正常工作?如何让一个绑定到分配给它们的布尔值?

请高人指教。

为了完整起见,下面是样式表,称为 lstyles.css:

#lstStyle {
   border: 4px solid #0055AA;
   width: 100%; 
   height: 400px;
   float: left;
}

.grpcheck {
   position:relative;
   top: 10px;
   left: 10px;
}

复选框问题,续

感谢 donMateo,我做了一些更改,让我可以显示网格。一旦能够显示它,我就开始单击复选框以查看它们是否有效。他们没有 - 或者更确切地说,他们没有按照我希望的方式工作。

问题 1: 我注意到的第一件事是复选框状态不反映它们绑定的数据。无论 isMovie 和 isCartoon 的值如何,每个节目的复选框都未选中。例如:Johnny Quest 将 isCartoon 设置为“true”。该列表将该框显示为未选中。星球大战侠盗一号将 isMovie 设置为 true。它的 isMovie 框未选中。 Figure 1 显示我所看到的。

注意:此站点上嵌入的图像不起作用。即使链接图像似乎也被破坏了。我提供了指向我的网站的直接 HTTP 链接,希望它们足以说明。

我更改了我的选择代码,以便它调用一个函数,该函数显示一个警告框,其中显示了节目名称、isMovie 值和 isCartoon 值的值。选择 Johnny Quest,我看到 isMovie 和 isCartoon 值是正确的。所以我的第一个问题是:为什么复选框不反映其数据的值?

问题 2: 我发现的另一个问题是,当我单击一个复选框时,它似乎没有保留我所做的更改。 Figure 2 显示当我单击 Johnny Quest 的 isMovie 复选框时会发生什么。请注意,该复选框已选中,但警告框仍将 isMovie 值显示为 false。请注意,警报显示在复选框更改状态之后。

当我单击警报框的“确定”按钮时,请注意 Figure 3 中的复选框如何返回“未选中”状态。其实我们在Figure 2看到勾选框的唯一原因就是因为alert框造成的延迟!我知道这一点,因为作为一个实验,我暂时删除了警告框,刷新了浏览器,然后单击了 Johnny Quest 的电影复选框。有一个复选框被按下的简短指示,然后复选框又回到未选中状态。所以我的第二个问题是:为什么复选框在选中或未选中时不显示适当的更改?

问题 3: 我发现的第三个也是最令人不安的事情是,复选框的状态显然发生了变化——但它并没有显示出这种变化,而且(更糟糕的是)它不会导致人们期望的变化。这可以通过重新显示网格中的数据来证明,在我的例子中是通过对数据进行排序。

当我启动网格时,显示的顺序是Figure 1 中显示的顺序。如果我点击“显示名称”列,排序列表看起来像Figure 4

然后我点击 Johnny Quest 电影复选框,得到警告框,点击 Ok。 Figure 5 显示复选框仍然保持不变。

现在,当我再次点击“显示名称”列时,为了进行反向排序,请注意Figure 6 中的所有电影复选框会发生什么!

卡通复选框也会发生同样的事情。单击一个,单击警报框上的确定,然后采取措施。所有卡通复选框都会被选中。

要取消选中它们,只需单击一个复选框,注意警告框中显示的不正确状态,单击确定,然后采取措施。将取消选中所有框。

所以我的第三个问题是:不同行中的复选框之间的链接是什么?更重要的是:我如何切断这个链接???

总结: 在将控件放入自定义列时,KoGrod 确实搞砸了。对于复选框:复选框显示的数据与假定绑定到的单个数据设置不同步。尝试更改复选框的选中状态不起作用,并且更改一个复选框会导致所有复选框都更改 - 但在重绘网格(使用排序或可能的滚动或分页)之前您不会看到该更改。

这就引出了一个问题:单元格模板是否只是作为网格的显示模板? koGrid 甚至能够正确处理包含控件的自定义列吗?如果是这样,怎么做?没有,那我在哪里可以找到一个网格控件呢?

请高人指教。

下面提供了当前的 testgrid.js。没有其他文件被更改。

var theList = [
               { isMovie: false, isCartoon: true, name: "Johnny Quest" },
               { isMovie: true, isCartoon: true, name: "Heavy Metal" },
               { isMovie: true, isCartoon: false, name: "Star Wars Rogue One" },
               { isMovie: false, isCartoon: false, name: "The Invaders" },
               { isMovie: true, isCartoon: false, name: "Star Trek: The Voyage Home" },
               { isMovie: false, isCartoon: true, name: "Space Ghost" },
               { isMovie: false, isCartoon: false, name: "Star Trek Classic" },
               { isMovie: false, isCartoon: false, name: "Lost In Space" },
               { isMovie: false, isCartoon: true, name: "Bugs Bunny/Road Runner Hour" },
           ];

var showTitles = [
              {field: 'isMovie',displayName: 'Movie',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: $data.isMovie' />"},
              {field: 'isCartoon',displayName: 'Cartoon',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: $data.isCartoon' />"},
              {field: 'name',displayName: 'Show Name',width: '78%'},
          ];

var TestModel = function() {
   var self = this;

   self.theData = ko.observableArray(theList);
   self.selectShow = ko.observableArray([]);

   self.instantiateSelf = function() {
        ko.applyBindings(theModel);
   }

   self.displaySelect = function() {
      alert("Show Selected: "+self.selectShow()[0].name+" Movie: "+self.selectShow()[0].isMovie+" Cartoon: "+self.selectShow()[0].isCartoon);
   }

   self.listOptions = {
        afterSelectionChange: function () { self.displaySelect(); },
        data: self.theData,
        selectedItems: self.selectShow,
        displaySelectionCheckbox: false,
        multiSelect: false,
        columnDefs: showTitles
   }
}
var theModel = new TestModel();

【问题讨论】:

    标签: javascript knockout.js kogrid


    【解决方案1】:

    这是您的“修复”代码:

    var theList = [
               { isMovie: false, isCartoon: true, name: "Johnny Quest" },
               { isMovie: true, isCartoon: true, name: "Heavy Metal" },
               { isMovie: true, isCartoon: false, name: "Star Wars Rogue One" },
               { isMovie: false, isCartoon: false, name: "The Invaders" },
               { isMovie: true, isCartoon: false, name: "Star Trek: The Voyage Home" },
               { isMovie: false, isCartoon: true, name: "Space Ghost" },
               { isMovie: false, isCartoon: false, name: "Star Trek Classic" },
               { isMovie: false, isCartoon: false, name: "Lost In Space" },
               { isMovie: false, isCartoon: true, name: "Bugs Bunny/Road Runner Hour" },
           ];
    var showTitles = [
              {field: 'isMovie',displayName: 'Movie',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: $data.isMovie' />"},
              {field: 'isCartoon',displayName: 'Cartoon',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: $data.isCartoon' />"},
              {field: 'name',displayName: 'Show Name',width: '78%'},
          ];
    var showTitles = [
              {field: 'isMovie',displayName: 'Movie',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: $data.isMovie' />"},
              {field: 'isCartoon',displayName: 'Cartoon',width: '10%',cellTemplate: "<input type='checkbox' class='grpcheck' data-bind='checked: $data.isCartoon' />"},
              {field: 'name',displayName: 'Show Name',width: '78%'},
          ];
    var TestModel = function() {
    var self = this;
    
    self.theData = ko.observableArray(theList);
    self.selectShow = ko.observableArray([]);
    
    self.instantiateSelf = function() {
       ko.applyBindings(theModel);
    }
    
    self.listOptions = {
      afterSelectionChange: function () { alert("Show Selected: "+self.selectShow()[0].name); },
      data: self.theData,
      selectedItems: self.selectShow,
      displaySelectionCheckbox: false,
      multiSelect: false,
      columnDefs: showTitles
    }
    }
    

    问题是“theData”,它是记录的未定义属性。不得不将其更改为 $data。 并在选择处理程序中添加自我。处于警戒状态。

    【讨论】:

    • 看起来这些更改已经解决了让网格显示的直接问题。但是,还有其他问题:复选框的状态不反映值,并且在单击时它们不保留其状态。我应该在这里描述问题还是应该开始另一个问题?
    • 这篇文章是解决我相信的这段代码的所有问题的好地方:)
    • 好的,然后:我将编辑我的原始帖子。做好准备:它将显着增长......
    • @Factor 3 哦,男孩,这是一个巨大的 :) 你能提供完整的小提琴吗?
    • 以前从来没有这样做过,不知道怎么做。
    猜你喜欢
    • 1970-01-01
    • 2018-03-14
    • 2017-12-17
    • 2020-01-12
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    相关资源
    最近更新 更多