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) { 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); }, } });
|
在开发时,首先引入公共方法util
1 2
| define(['san', 'util'], function (san, util) { }
|
然后在需要改变数据的地方,对原始数据进行深拷贝,修改数据的值后,再通过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);
|