如何在gridx的cell中显示控件

 我来答
匿名用户
推荐于2016-09-25
展开全部
  在gridx的列定义中,一个decorator方法可以被用来在cell中显示任何HTML/CSS. 但是有时候这稍显不够。当cell中需要放入复杂的控件时,从decorator方法中返回的纯string不再有效。所以gridx/modules/CellWidget模块在这是显示了作用。

  为何是CellWidget

  CellWidget模块通过grid的body模块中的onAfterRow事件将widget附加到cell节点中。其中的关键是如何才能高效地完成这个工作。

  Grid的body随着时间不断刷新,刷新的原因可以是排序,过滤,分页,虚拟滚动,改变值,展开树节点,等等。每次body被刷新,行被重新,并且onAfterRow事件将会被处罚。如果我们总是在onAfterRow事件中创建新的widget,那将会非常浪费。如果你点击header两次为了要是的一列降序排序,许多widget将会被立刻摧毁。所以一些缓存机制必须被建立。第一个方法是为在每个cell中使用一个widget,无论被刷新多少次。这解决了一些刷新问题,但是如果我们有100000行,这仍然不高效。试想如果一个用户慢慢地滚动这个巨大的grid来看每一行,最终将会有多少widget被创建!

  所以CellWidget的目的是创建尽可能少的控件。方法是使用set('value',...)方法在row之间重用控件。

  如何使用CellWidget

  在控件上设置值通常比创建一个新控件快。这是一个好方法,但是需要用户意识到重用这件事情。让我们首先看一下如何使用CellWidget模块:

  var grid = new Grid({
  cacheClass: 'gridx/core/model/cache/Async',
  store: someStore,
  structure: [
  { id: 'progress', field: 'progress', name: 'Install Progress',
  widgetsInCell: true,
  decorator: function(){
  return "<div data-dojo-type='dijit.ProgressBar' data-dojo-props='maximum: 1' " +
  "class='gridxHasGridCellValue' style='width: 100%;'></div>";
  }
  }
  ],
  modules: [
  "gridx/modules/CellWidget"
  ]
  });

  首先,不要忘记载入所有必要的资源: store, cache, 模块和你想要在cell中展示的widget。如果你仍然在创建一个gridx的时候遇到麻烦,请阅读 这篇教程 .
  第二,在你想要显示widgets的列中将 widgetsInCell 属性设置为true。CellWidget模块将只会在这些列上有效。
  第三,在你的设置 widgetsInCell 的列中提供 decorator 方法。

  从decorator方法中返回模板字符串

  这里你将看到第一个小技巧: decorator 并没有任何的参数。这并不是当 widgetsInCell 为false的情况。通常当前的cell数据会被传入,和row Id和Index一起。如果某些特定的cell数据被传入,我们将如何重用他们?所以这个template string不能包含任何特定的行信息。在上面的示例中,一个dijit/ProgressBar被放进template中,他的参数可以在data-dojo-props中被加入。注意这个 gridxhasGridCellValue class ,这是关于widgets被重用的第二个技巧。CellWidget模块将会在渲染每一行时自动查找所有含有这个class的widget,并且调用set('value')在widget中设置合适的值。

  在setCellValue中设置widgets

  在上面的例子中,在调用 widget 的 set('value') 之前不需要转换数据,因此事情显得比较简单。在设置widget值的时候,如果你想做一些有趣的事情,该怎么办? setCellValue 方法在这个时候派上了用处。
  { id: 'progress', field: 'progress', name: 'Install Progress',
  widgetsInCell: true,
  decorator: function(){
  return "<div data-dojo-type='dijit.ProgressBar' data-dojo-props='maximum: 1' " +
  "data-dojo-attach-point='progBar' style='width: 100%;'></div>";
  },
  setCellValue: function(gridData, storeData, cellWidget){
  var data = doSomethingIntersting(gridData);
  cellWidget.progBar.set('value', data);
  // cellWidget.cell give you full access to everything you want.
  var rowIndex = cellWidget.cell.row.index();
  }
  }
  setCellValue 方法会在每一行被render的时候被调用。当这个方法被调用时,widget已经被创建并且你能完全控制widget。你可以在widgets上设置值,改变css,或者操纵dom节点并且添加事件。这个方法中的第三个参数'cellWidget'引用了cell widget本身,这是拥有从'decorater'方法中返回的template string的widget,所以你可以访问任何的在控件中定义的“dojo attach point”。第一和第二个参数是当前cell的grid data与store data。他们只有当'formatter'方法被提供时才会有差别。你可以通过cellWidget.cell来获取当前的cell,从中你可以获取任何你需要的东西。

  如何处理widget事件

  但是请记住widgets("cell widget"作为一个整体)是在不同的行之间被重用。所以如果你在setCellValue方法中绑定了一些事件或者改变了一些dom节点的时候,这些改变将会在被其他行重用时被保留。如果你一直连接事件而不断开事件,将会有巨大的内存泄漏风险。所以合适的方法是在setCellValue中连接并且断开事件。例如

  { id: 'progress', field: 'progress', name: 'Install Progress',
  widgetsInCell: true,
  decorator: function(){
  return "<button data-dojo-type='dijit.form.Button' data-dojo-attach-point='btn'></button>";
  },
  setCellValue: function(gridData, storeData, cellWidget){
  cellWidget.btn.set('label', gridData);
  if(cellWidget.btn._cnnt){
  // Remove previously connected events to avoid memory leak.
  cellWidget.btn._cnnt.remove();
  }
  cellWidget.btn._cnnt = dojo.connect(cellWidget.btn, 'onClick', function(e){
  alert(gridData);
  // do your job here......
  });
  }
  }

  我承认,这看起来不怎么直观。所以在gridx 1.2中一个新的方法(回调)在会被引入以使得这个工作更加简便:

  { id: 'progress', field: 'progress', name: 'Install Progress',
  widgetsInCell: true,
  decorator: function(){
  return "<button data-dojo-type='dijit.form.Button' data-dojo-attach-point='btn'></button>";
  },
  setCellValue: function(gridData, storeData, cellWidget){
  cellWidget.btn.set('label', gridData);
  },
  getCellWidgetConnects: function(cellWidget, cell){
  // return an array of connection arguments
  return [
  [cellWidget.btn, 'onClick', function(e){
  alert(cell.data());
  // do your job here.....
  }]
  ];
  }
  }
  有了这个getCellWidgetConnects,gridx可以为你管理事件链接(句柄)。连接和断开都会被自动执行。

  其他高级的回调函数

  初次之外,gridx 1.2添加了另外2个方法来为你的工作提供更加有意义的命名:

  { id: 'progress', field: 'progress', name: 'Install Progress',
  widgetsInCell: true,
  decorator: function(){
  return "<button data-dojo-type='dijit.form.Button' data-dojo-attach-point='btn'></button>";
  },
  setCellValue: function(gridData, storeData, cellWidget){
  cellWidget.btn.set('label', gridData);
  },
  getCellWidgetConnects: function(cellWidget, cell){
  // return an array of connection arguments
  return [
  [cellWidget.btn, 'onClick', function(e){
  alert(cell.data());
  // do your job here.....
  }]
  ];
  },
  initializeCellWidget: function(cellWidget, cell){
  // create extra widgets or manipulate dom nodes that depends on current cell context.
  cellWidget.anotherButton = new Button({...});
  cellWidget.domNode.append(cellWidget.anotherButton.domNode);
  },
  uninitializeCellWidget: function(cellWidget, cell){
  // don't forget to undo the changes you made in initializeCellWidget, so that it can be reused among different rows.
  cellWidget.anotherButton.destroy();
  }
  }
  如你所见,事实上你可以在setCellValue方法中做这些事情。这个新方法只是提供了更多的语义,使你的代码更加易于阅读并且省去了你添加额外的注释的功夫。

  创建控件的编程方式

  如果你 曾经用过DataGrid , 你可能会对于在 f ormatter 方法中返回widget的方式感到熟悉,并且对于写 t emplate string的方式感到 变扭。因此你可以使用 onCellWidgetCreated 事件,甚至 省略“ decorator ” 方法(gridx 1.2之后) :
  { id: 'progress', field: 'progress', name: 'Install Progress',
  widgetsInCell: true,
  onCellWidgetCreated: function(cellWidget, column){
  var btn = new Button({...});
  btn.placeAt(cellWidget.domNode);
  }
  }

  onCellWidgetCreated 只当一个新的cell widget被创建 时 被调用。它不会在widget 重用时 被调用。跟decorator 方法 相同,不应该在此处使用特定行的信息。
  以下是如何在gridx的cell 中显示widget的结论:

  为grid 引入 gridx/moduels/CellWidge t模块
  在列设置中将 widgetsIn Cell 设置为true
  在 decorator 方法 中返回模板string ,或者在 onCellWidgetCreated 事件处理 函数中创建 控件,或者两者皆执行
  在 setCell Value 方法中设置widget的值(可选)
  在 getCellWidgetConnects 中提供 事件 连接(可选, gridx 1.2 之后 )
  在 initialCellWidget 和 Uninit ialCellWidget 中做额外的操作(可选,gridx 1.2之后)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式