san框架官方文档:https://baidu.github.io/san/tutorial/start/

san框架遇到数组深层做数据修改时,直接 set 数据会发现没有触发视图的更新,但是将数据打印在控制台上发现数据确实是已经进行了修改。

San 的数据变更在内部是 Immutable 的,因此遇到数组深层做数据交换时直接 set 数据会发现没有触发视图的更新。

因为直接set赋值后,相当于是一种浅拷贝,浅拷贝拷贝的是引用地址,san内部监测到数据的引用地址没变,默认判定数据没变,所以就没有触发视图的更新。要想在深层数据修改后触发视图更新,就要对数据进行深拷贝。(深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。)

深拷贝方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
define(function (require) {
var _cloneObj = function (obj) { //深度copy方法
var str, newobj = obj.constructor === Array ? [] : {};
if (typeof obj !== 'object') {
return;
} else if (window.JSON) {
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for (var i in obj) {
newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};

return {
cloneObj: function (obj) {
return _cloneObj(obj);
},
}
});
  1. 在开发时,首先引入公共方法util

    1
    2
    define(['san', 'util'], function (san, util) {
    }
  2. 然后在需要改变数据的地方,对原始数据进行深拷贝,修改数据的值后,再通过this.data.set(‘xxx’,data)的方式修改数据,触发视图更新

1
2
3
4
5
6
7
8
let selectedList = util.cloneObj(self.data.get('selectedList'));
let index = 5;
selectedList[index].malltRightsResourceSelecteds = res.busiDataResp;
let i=0; for(i;i<selectedResourceList[index].malltRightsResourceSelecteds.length;i++){
selectedList[index].malltRightsResourceSelecteds[i].grandType = '';
selectedList[index].malltRightsResourceSelecteds[i].isUnsubscribe = '';
}
self.data.set("selectedList",selectedList);