【问题标题】:When declaratively creating a dojox.grid.DataGrid - how to specify nested data in the field attribute?以声明方式创建 dojox.grid.DataGrid 时 - 如何在字段属性中指定嵌套数据?
【发布时间】:2011-08-23 03:02:12
【问题描述】:

我正在使用以下符号在 dojo 1.6 中创建 dojox.grid.DataGrid:

<table dojoType="dojox.grid.DataGrid">
  <thead>
    <tr>
      <th field="id">ID</th>
      <th field="contact.name">Name</th>
      <th field="contact.tel">Telephone</th>
      <th field="contact.birthdate.time">Birthday</th>
    </tr>
  </thead>
</table>

数据看起来像这样:

[{
'id':1,
'contact':{
  'name':'Doh', 
  'firstname':'John',
  'tel':'123-123456',
  'birthdate':{
    'javaClass':'java.sql.Timestamp',
    'time':1234567893434}}
}]

ID 被正确呈现,但所有其他都呈现为“...”。 我试图指定一个格式化程序,将基本对象“联系人”设置为 FIELD,然后返回 FIELD.name 例如。 到目前为止,这可以显示正确的值,但是排序然后 使用基础对象。

我认为可能有一种方法可以进一步推动这一点,覆盖排序 表,但我想尽可能简单。

我还希望防止出现性能问题。

有什么想法吗?

【问题讨论】:

    标签: dojo dojox.grid.datagrid


    【解决方案1】:

    我发现DataGrid 行定义有一个属性称为“get”。 “get”指定返回要在 DataGrid 列中显示的值的函数的名称。

    理论上这应该可以解决我的问题。

    get-function的实现方式如下:

    网格定义:

    <table dojoType="dojox.grid.DataGrid">
      <thead>
        <tr>
          <th field="id">ID</th>
          <th field="contact" get="myGrid.getContactName">Name</th>
          <th field="contact" get="myGrid.getContactTel">Telephone</th>
          <th field="contact" get="myGrid.getContactBirthdateTime">Birthday</th>
        </tr>
      </thead>
    </table>
    

    回调函数(示例):

    myGrid.getContactName = function(colIndex,item){
      return item.name;
    };
    

    目前我无法判断此实现是否正确,因为 item 参数在我的应用程序中始终为 null。

    这可能是由于使用了新的 Store API (store.Memory) 而不是 ItemFileReadStore,但我还没有成功解决这个难题。

    我也无法用这种新方法测试网格排序,所以我不会标记 该解决方案尚未解决。

    更新

    myGrid.getContactName = function(colIndex,record){
      if(record)return record.contact.name;
      else return null;
    };
    

    一旦我避免了 null 情况,它就可以正常工作。

    但是,Grid 的客户端类型似乎不通过 get 函数访问,而是直接使用该字段。这会阻止对嵌套字段进行正确排序。

    更新

    我终于找到了解决问题的方法:

    第一个问题:为 DataGrid 字段指定嵌套数据已完全解决,使用 get 函数深入到数组子结构中。 (上面已经解释过了)

    然而,排序仍然依赖于字段属性。 如果字段属性包含数组的名称,则此列将无法正确排序。

    我不得不修改一些 dojo 类来适应这一点。稍后我将把它放在一个更模块化的形式中,但这里是现在的原始结果:

    首先,我需要允许在网格定义中定义额外的比较器回调。 为此,我在 dojox.grid.cells._base 中添加了一些代码

    dgc._Base.markupFactory = function(node, cellDef){
    var d = dojo;
    ...
    var comparator = d.trim(d.attr(node,"comparator")||"");
    if(comparator){
      cellDef.comparator = dojo.getObject(comparator);
    }
    ...
    }
    

    接下来,DataGrid 需要将此新参数提供给查询以进行排序。 这是在 dojox.grid.DataGrid 中完成的。 “c”是我在上面修改的单元格。

    getSortProps:function(){
    ...
    return[{attribute:c.field,descending:desc,comparator:c.comparator}];
    }
    

    最后,我需要更改在 dojo.store.util.SimpleQueryEngine 中定义的排序本身。 SimpleQueryEngine 是 MemoryStore (dojo.store.Memory) 的默认引擎。

    function execute(array){
        // execute the whole query, first we filter
        var results = dojo.filter(array, query);
        // next we sort
        if(options && options.sort){
            results.sort(function(a, b){
                for(var sort, i=0; sort = options.sort[i]; i++){
                    var aValue = a[sort.attribute];
                    var bValue = b[sort.attribute];
                    if (aValue != bValue) {
                        // changed Part start
                        if(options.sort[i].comparator){ 
                            return !!sort.descending == options.sort[i].comparator(aValue,bValue) ? -1 : 1;
                        }
                        else{
                            return !!sort.descending == aValue > bValue ? -1 : 1;
                        }
                        // changed Part end
                    }
                }
                return 0;
            });
        }
        ...
        return results;
    }
    

    现在我可以为每一列添加比较器并在我想要的位置定义它们:

    声明性 DataGrid 设置:

    ...
    <td field="myArray" get="getsNameFromArray" comparator="comparesNames">Name</td>
    ...
    

    比较器函数的Javascript定义(a和b是“myArray”对象):

    compareNames = function(a,b){
      return a.name > b.name;
    }
    

    getter 函数的 Javascript 定义(记录为整行,包含“myArray”对象):

    getNamesFromArray= function(idx,record){
      return record.myArray.name;
    }
    

    【讨论】:

    • 临时结果改变了基本的dojo类。一旦代码被清理以模块化使用,我将重写答案以获得更好的可读性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 2021-06-15
    • 2011-02-25
    • 2011-08-26
    • 2014-08-06
    • 2023-03-16
    • 2020-08-29
    相关资源
    最近更新 更多