# Fix中对数组、对象的操作技巧 Fix编程中状态控制采用数组,对象等非基础数据类型的场景很多,相信大多数人在接触Fix的时候都会遇到这些困惑:"为什么我明明改了值,但是没watch到呢?" 下面结合几个示例 ## 修改数组内子元素,期望watch到数组改变 对数组进行push,pop会可以watch到数组的变化,这是我们所熟知的 我们修改了列表中的某一项,期望触发watch,从而重新渲染整个列表,但是并未得偿所愿. ```javascript state: function () { return { arr: [{ value: 1 }, { value: 2 }], }; }, watch: { arr: function () { console.log(this.model.arr); // do populate }, }, actions: { changeArr: function () { // 这样写法并不能触发watch this.model.arr[0] = { value: 0 }; }, }, ``` 从内部原理上讲可以简单理解为修改数组的某一项,整个数组的引用并未发生改变,所以也就不会触发通知. 那想办法使数组的引用变了就可以了.常用的技巧是使用`splice`方法 ```javascript // 利用splice修改某个索引位置元素 this.model.arr.splice(0, 1, { value: 0 }); // 或者通过splice(0, 0)的技巧触发数组引用改变.常用于修改较深层次的对象解构,用该方式触发数组watch this.model.arr[0].value = 0; this.model.arr.splice(0, 0); ``` ## 修改了对象的某个属性,期望watch到对象变化 修改对象属性,增删改属性,想通过watch到整个obj的变更来进行重新渲染. (对象属性可以通过obj.* Fix.set等方式处理,暂不在本篇论述) ```javascript state: function () { return { obj: { a: 1, }, }; }, watch: { obj: function () { console.log(this.model.obj); }, }, actions: { changeArr: function () { // 这样写法并不能触发watch this.model.obj.a = 2; this.model.obj.b = 1; }, }, ``` 同对数组的操作一样,我们同样需要想办法改变对象的引用.常用的方法是使用传统`BI.extend`或者es6的解构操作符 ```javascript // 通过解构产生一个全新的对象 this.model.obj = { ...this.model.obj, a: 2, b: 1 }; // 类似于Object.assign,注意用第一个参数的空对象来产生新的引用 this.model.obj = BI.extend({}, this.model.obj, { a: 2, b: 1 }); ```