You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.5 KiB

2 years ago
# 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 });
```