typeで配列型を指定した場合の挙動
配列型が保持する値
データモデルのディスクリプタで、type:"string[]" のように配列型を指定したプロパティは通常の配列ではなくObservableArrayになります。
データアイテムがcreateされた時に、配列型要素について新しくObservableArrayインスタンスを作成して、常にこのインスタンスを持ちます。
値を変更してもインスタンスが変わることはありません。
name: 'SampleModel',
schema: {
id: {
id: true
},
items: {
type: 'any[]'
}
}
});
var dataItem = dataModel.create({
id: '001'
});
// 配列プロパティの初期値は空のObservableArray
var oAry = dataItem.get('items');
// copyFromを使って配列の中身をコピー
// oAry.set('items', [1, 2, 3]); と同じ
oAry.copyFrom([1, 2, 3]);
alert(oAry); // [1, 2, 3]
// データアイテムが持つ値のインスタンスは変わらない
dataItem.set('items', [4, 5, 6]);
dataItem.get('items') === oAry; // true
配列をメソッドで操作した時に、型チェック・制約チェック・イベントの発火等を行っています。
配列の中身が変更された場合は、
メソッドを使わずに中身を入れ替えた場合、これらは行われません。
そのため、データモデルの配列の操作は、必ずObservableArrayのインスタンスが持つメソッドを使用してください。
// oAryに値を追加
o.push(4);
// oAryの2番目(o[2])の値を22に変更
o.splice(2, 1, 22);
// o[2] = 22; とやっても値は変わるが、変更イベントは上がらない。
item.get('items'); // [1, 22, 3, 4]
nullをセットした時の挙動
配列型を指定したプロパティに、nullをセットすることができます。nullをsetした場合、getで取得できるのは空配列です。
var obsAry = item.get('array'); // [1, 2] のObservableArray
// nullをセット
item.set('array', null);
item.get('array'); // [] 空のObservableArray
obsAry === item.get('array'); // インスタンスは変わらない
基本的には、空配列をセットした場合と挙動は変わりません。
しかし、regardAsNull()メソッドで、nullがセットされたのか、空配列がセットされたのか区別することができます。
詳細はAPIをご覧ください。DataItem#regardAsNull
// ※ arrayプロパティはtype:'any[]'で、defaultValueが設定されていない。
var item = model.create({id:'1'});
item.get('array'); // [] 初期値なので空のObservableArray
item.regardAsNull('array'); // true 初期状態はtrue
item.set('array', []);
item.get('array'); // [] 空配列をセットしたので空のObservableArray
item.regardAsNull('array'); // false 空配列がセットされた状態はfalse
item.set('array', null);
item.get('array'); // [] nullをセットしたので空のObservableArray
item.regardAsNull('array'); // true nullがセットされた状態はtrue
イベントオブジェクト内の配列プロパティ
データアイテムのchangeイベントオブジェクトには、変更前の値と変更後の値が格納されます。しかし、typeに配列指定されたプロパティは、値はObservableArrayであるため、その要素の変更が行われてもインスタンスは変わりません。
そのため、変更前の要素が分かるよう、typeに配列指定されたプロパティのoldValueには、変更前時にObservableArrayが持っていた要素を持つ通常の配列を作成して格納してあります。
id: '001',
ary: [1, 2, 3]
});
item.addEventListener('change', function(ev) {
ev.props.ary.oldValue; // ただの配列で、[1, 2, 3]
ev.props.ary.newValue; // ObservableArrayで、[4, 5, 6]
});
item.set('ary', [4, 5, 6]);