「get」と呼ばれるDataGrid行定義の属性があることがわかりました。「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であるため、この実装が正しいかどうかは現時点ではわかりません。
これは、ItemFileReadStoreの代わりに新しいStore API(store.Memory)を使用していることが原因である可能性がありますが、このパズルを解くのにまだ成功していません。
また、この新しいアプローチではGirdの並べ替えをテストできなかったため、このソリューションに解決済みのフラグを立てることはまだありません。
アップデート
myGrid.getContactName = function(colIndex,record){
if(record)return record.contact.name;
else return null;
};
ヌルケースを回避すると、このように正常に機能しました。
ただし、グリッドのクライアントソートは、get関数を介してアクセスするようには見えませんが、フィールドを直接使用します。これにより、ネストされたフィールドでの正しい並べ替えができなくなります。
アップデート
私はついに私の問題の解決策を得ました:
最初の問題:DataGridフィールドにネストされたデータを指定することは、get-functionを使用して配列の下部構造に飛び込むことですでに解決されました。(それは上で説明されています)
ただし、並べ替えはフィールド属性に依存します。フィールド属性に配列の名前が含まれている場合、この列は正しくソートされません。
それに対応するために、いくつかの道場クラスを変更する必要がありました。後でこれをよりモジュール形式に変換しますが、今のところ生の結果は次のとおりです。
最初に、グリッド定義で追加のコンパレータコールバックの定義を許可する必要がありました。そのために、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;
}