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.
 

2.5 KiB

Fix中对数组、对象的操作技巧

Fix编程中状态控制采用数组,对象等非基础数据类型的场景很多,相信大多数人在接触Fix的时候都会遇到这些困惑:"为什么我明明改了值,但是没watch到呢?"

下面结合几个示例

修改数组内子元素,期望watch到数组改变

对数组进行push,pop会可以watch到数组的变化,这是我们所熟知的 我们修改了列表中的某一项,期望触发watch,从而重新渲染整个列表,但是并未得偿所愿.

    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方法

    //  利用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等方式处理,暂不在本篇论述)

    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的解构操作符

    //  通过解构产生一个全新的对象
    this.model.obj = { ...this.model.obj, a: 2, b: 1 };
    //  类似于Object.assign,注意用第一个参数的空对象来产生新的引用
    this.model.obj = BI.extend({}, this.model.obj, { a: 2, b: 1 });