zuzuの開発日記

iMona@zuzu等の開発者であるzuzuの趣味や業務で学んだ事などを書き連ねるブログ

SpreadJSにおけるデータバインド機能備忘録

現在、今年5月に発売されたばかりの次世代JavascriptコンポーネントWijmo5とSpreadJSを活用したWebアプリケーションを作成している。 最新のJavascriptを触れるのは刺激的であるが、中々に大変だ。

さて、その開発中にWijmoやSpreadJSが持つオブジェクトとのデータバインド機能を利用した際に配列をうまくセルごとにバインドさせる方法が見つからなかったので、ここに備忘録として記述していく。 今後、備忘録その2が出るかもしれない。

SpreadJS.Sheet setBindingPathで配列にアクセスする方法

function setBindingPath( 
   row : number,
   col : number,
   path : string
) : any;

setBindingPathは行列と対象のオブジェクトを指定することで、その行列とオブジェクトを紐づけることが出来る。

ただし厄介なのは、setBindingPathの第3引数では、DataSourceに指定されたオブジェクトが持つフィールド名を指定する仕様となっている。

以下が例文となる。

var person = {name: "Wang feng", age: 25, address: {postcode: "710075"}};
var source = new $.wijmo.wijspread.CellBindingSource(person);
activeSheet.setBindingPath(0, 0, "name");
activeSheet.setBindingPath(1, 1, "age");
activeSheet.setBindingPath(3, 3, "address.postcode");
activeSheet.setDataSource(source);

では、DataSourceが連想配列ではなく配列だった場合はどうするのか?

以下が例となる。

var persons = [
{name: "Wang feng", age: 25, address: {postcode: "710075"}}.
{name: "August dog", age: 20, address: {postcode: "610075"}}
];
var source = new $.wijmo.wijspread.CellBindingSource(person);
activeSheet.setBindingPath(0, 0, "0.name");
activeSheet.setBindingPath(1, 1, "0.age");
activeSheet.setBindingPath(3, 3, "0.address.postcode");
activeSheet.setBindingPath(0, 1, "1.name");
activeSheet.setBindingPath(1, 2, "1.age");
activeSheet.setBindingPath(3, 4, "1.address.postcode");
activeSheet.setDataSource(source);

このように要素番号をまるでフィールドのように記述することでアクセスが可能となる。

これは下記に示す、BindingPathによるプロパティへのアクセス処理の実装を見れば納得できるだろう。

BindingPathをドットで区切り、区切ったものを対象のオブジェクトの要素名としてアクセスしているのだ。

※obj = 対象のオブジェクト。 p = ドットで区切ったアクセサ。

_BindingHelper.getValueByPath = function(obj, path)
{
    if (!obj || !path)
    {
        return keyword_null
    }
    var subpaths = path.split("."),
        subpathCount = subpaths.length;
    var i = 0;
    do
    {
        var p = subpaths[i];
        if (typeof(obj[p]) === 'function')
        {
            obj = obj[p]()
        }
        else
        {
            obj = obj[p]
        }
        if (obj === keyword_null || typeof(obj) === const_undefined)
        {
            return keyword_null
        }
    } while (++i < subpathCount);
    return obj
};
return _BindingHelper
広告を非表示にする