需要自定义复选框列才能在KoGrid中工作

问题描述:

我试图显示包含一些基本演示数据的KoGrid。该网格有一个嵌入式复选框,用于指示该节目是否为电影,另一个嵌入复选框用于指示该节目是否为卡通。 JavaScript的这个网,在一个名为testgrid.js,提供如下:需要自定义复选框列才能在KoGrid中工作

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定义中的“data-bind”语句。如果我删除这些语句,网格会显示,但我无法选中或取消选中复选框,也无法获取复选框的状态。

有没有办法让这些复选框在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”。该列表显示该框未被选中。星球大战盗贼One isMovie设置为true。其isMovie框未被选中。 Figure 1显示我所看到的。

注:图像嵌入在这个网站是行不通的。即使连接图像似乎也被打破。我正在向我的网站提供直接的HTTP链接,希望它们足以说明问题。

我改变了我的选择的代码,以便调用,显示出节目名称,isMovie值,和值isCartoon的值的警告框的功能。选择Johnny Quest,我发现isMovie和isCartoon的值是正确的。所以我的第一个问题是:为什么复选框没有反映他们数据的值?

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

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

问题3: 我发现的第三个也是最令人不安的事情是,显然状态是复选框的状态发生了变化 - 但它没有显示出这种变化,并且(更糟糕)它不会导致更改会期待。这可以通过重新显示网格中的数据来演示,在我的情况下通过排序数据。

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

然后我点击Johnny Quest电影复选框,得到警告框,点击确定。 Figure 5显示了该复选框仍未更改。

现在当我再次点击“显示名称”列时,为了做一个反向排序,请注意所有电影复选框在Figure 6

卡通复选框会发生同样的情况。点击一个,点击提示框上的确定,然后进行度假。所有卡通复选框将被检查。

要取消选中它们,只需点击一个复选框,注意警告框中显示的不正确状态,点击确定,然后再度假。所有的盒子都将被取消选中。

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

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

这会导致一个问题:单元格模板是否只是网格的显示模板? 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(); 

这里是你的 “修复” 代码:

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 
} 
} 

问题是 “海图”,这是创纪录的未定义的属性。必须将其更改为$数据。 并在选择处理程序添加自我。在警报中。

+0

它看起来像这些变化已经解决了获取网格显示的直接问题。不过,还有其他一些问题:复选框的状态不能反映这些值,并且在点击时不保留它们的状态。我应该在这里描述问题还是应该开始另一个问题? –

+0

这个帖子是解决所有问题的正确的地方,我相信:) – donMateo

+0

好的,那么:我将编辑我原来的帖子。做好准备:它会显着增长... –