При декларативном создании dojox.grid.DataGrid - как указать вложенные данные в атрибуте поля?

Я создаю dojox.grid.DataGrid в Dojo 1.6 со следующими обозначениями:

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

Идентификатор отображается в основном, но все остальные отображаются как "...". Я попытался указать форматер, установив базовый объект "контакт" в качестве поля, а затем, например, возвращая имя FIELD.name. Это работает до тех пор, пока отображается правильное значение, но сортировка затем использует базовый объект.

Я думаю, что мог бы быть способ продвинуть это еще дальше, переопределяя сортировку таблицы, но я хотел бы сделать это как можно более простым.

Также я хочу предотвратить появление проблем с производительностью.

Есть идеи?

1 ответ

Решение

Я обнаружил, что для определения строки DataGrid существует атрибут, называемый "get". "get" указывает имя функции, которая возвращает значение, отображаемое в столбце DataGrid.

Теоретически это должно решить мою проблему.

Функция get должна быть реализована следующим образом:

Определение сетки:

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

Я не могу сказать, в данный момент, является ли эта реализация правильной, так как параметр элемента всегда нулевой в моем приложении.

Это может быть связано с использованием нового API-интерфейса Store (store.Memory) вместо ItemFileReadStore, но мне пока не удалось решить эту головоломку.

Также я не смог протестировать сортировку Gird с этим новым подходом, поэтому я не буду отмечать это решение как решенное.

Обновить

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

Как только я предотвратил нулевой случай, все работало нормально.

Однако клиентская сортировка Grid, по-видимому, не доступна через функцию get, а использует поле напрямую. Это предотвращает правильную сортировку вложенных полей.

Обновить

Я наконец-то получил решение своих проблем:

Первая проблема: указание вложенных данных для полей DataGrid было решено уже с использованием функции get для погружения в подструктуру массивов. (это объясняется выше)

Однако сортировка по-прежнему зависит от атрибута поля. Если атрибут поля содержит имя массива, этот столбец будет отсортирован неправильно.

Я должен был изменить несколько классов додзё, чтобы приспособиться к этому. Позже я изложу это в более модульной форме, но вот предварительный результат:

Сначала мне нужно было разрешить определение дополнительного обратного вызова компаратора в определении сетки. Для этого я добавил код в 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. "с" - это ячейка, которую я модифицировал выше.

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

Javascript-определение функции getter (запись - это целая строка, содержащая объект myArray):

getNamesFromArray= function(idx,record){
  return record.myArray.name;
}
Другие вопросы по тегам