>

Models

如果没有特殊要求,你可以直接使用普通的Object和Array来提供数据。如果需要观察数据对象内部属性的变化,则可以使用Exact提供的Store和Collection。

Store for Object

Store实例可发送属性更改的通知,所以它可作为绑定源。 使用实例方法set设置一个属性时,会为这个属性创建一对特殊的getter/setter,在属性值发生更改时可派发changed类型事件。 通过构造函数、create或者save法都会间接地调用set方法。

var store = Exact.Store.create({x: 0}); // 会为`x`创建getter/setter
store.on('changed', function(event) {
  console.log(event.keyName, store[event.keyName]);
});
store.x = 1;        // 输出:"x" 1
store.y = 2;        // 没有输出
store.set('y', 2)   // 为`y`创建getter/setter,并输出:"y" 2
store.y = 3;        // 输出:"y" 3
store.z = 3;        // 没有输出
store.save({z: 3})  // 为`z`创建getter/setter,并输出:"z" 3
store.z = 4;        // 输出:"z" 4

Collection for Array

Collection继承自Array,重写了`push`等改变自身结构的方法,以保证当一个Collection对象发生增删或替换时,就会触发`changed`事件。 用例如下:

var collection = new Exact.Collection(1,2,3);
console.log(collection)       // 输出:[1,2,3]
collection = Exact.Collection.from([0,1,2]);
console.log(collection)       // 输出:[0,1,2]
collection.on('changed', function() {
  console.log(collection);
});
collection.push(3, 4);        // 输出:[0,1,2,3,4]
collection.unshift(-1);       // 输出:[-1,0,1,2,3,4]
collection.pop();             // 输出:[-1,0,1,2,3]
collection.shift();           // 输出:[0,1,2,3]
collection.splice(2, 0, 1.5); // 输出:[0,1,1.5,2,3]

Collection没有重写`slice`等不改变自身结构的方法,这些方法依然返回新的数组而非新的Collection对象。 由于ES5的限制,通过索引下标来赋值和直接修改collection的长度,都无法触发`changed`事件,建议使用如下方法替代:

collection.set(index, item); // 替代collection[index] = item;
collection.splice(length);   // 替代collection.length = length;

Collection额外提供了`insert`、`remove`和`replace`三个方法,类似于DOM子节点操作方法中的`insertBefore`、`removeChild`和`replaceChild`,用法如下:

var collection = new Exact.Collection();
// 末尾插入
collection.insert({x: 1});
collection.insert({x: 2});                // [{x: 1}, {x: 2}]
// 在某个已有元素之前插入
collection.insert({x: 0), collection[0]); // [{x: 0}, {x: 1}, {x: 2}]
// 移除已有元素
collection.remove(collection[1]);         // [{x: 0}, {x: 2}]
// 替换已有元素
collection.replace({x: 1}, collection[1]);// [{x: 0}, {x: 1}]