开发
API
自2022年9月6日起,本文档站不再更新内容,相关文档已迁移至全新“抖音开放平台”前往

数据监听器 observers

基础库 2.44.0 开始支持。

数据监听器可以用于监听和响应自定义组件任何属性和数据字段的变化,触发监听回调。

使用说明

有时,在使用 setData 设置某些数据字段时,需要执行一些额外的操作。

例如, 某场景下,需要保持 this.data.sum 一直等于 this.data.numberAthis.data.numberB 的和。可以在 Component 函数中定义 observers 字段,代码如下:

Component({
  attached() {
    this.setData({
      numberA: 1,
      numberB: 2,
    });
  },
  observers: {
    // 在更新 this.data.numberA 或 this.data.numberB 时,执行这个函数
    "numberA, numberB"(numberA, numberB) {
      this.setData({
        sum: numberA + numberB,
      });
    },
  },
});

监听语法

observers 是 object 类型,它的 key 是监听表达式,value 是触发监听的回调函数,监听表达式的类型如下:

说明
只包含一个 keya 表示监听 this.data.a
. 分隔的路径表达式a.b.c 表示监听 this.data.a.b.c
路径表达式含有数组下标a[0] 表示监听 this.data.a[0]
路径表达式结尾含有通配符 **** 表示监听 this.data 任意子路径的变化, a.** 表示监听 this.data.a 任意子路径的变化,如 this.data.a, this.data.a.b.c 等。
, 分隔的多路径表达式a, b 表示同时监听 this.data.athis.data.b

监听回调的参数与监听表达式的每条路径一一对应。举例如下:

  • a, b 的监听回调依次传入 this.data.a, this.data.b 两个参数;
  • a.** 的监听回调传入的参数是 this.data.a
  • ** 的监听回调传入的参数是 this.data

observers 的触发时机

  • 只有属性更新或通过 setData 更新才可能触发数据监听器,直接修改 data 如 this.data.xxx = 'xxx' 不会触发数据监听器;
  • 如果监听的是自定义组件 properties 定义的属性,父组件初始化时给子组件的被监听的属性赋值,也会触发监听回调;
  • 如果 setData 涉及的数据字段的值没有发生变化(与旧值做深比较),则它们不会触发数据监听器;
  • 如果 propertiesobservers 同时定义了对同一个数据字段的监听回调,触发顺序是先触发 observers 的回调,再触发 properties 中定义的回调。

代码示例

Component({
  observers: {
    "some.subfield"(subfield) {
      // this.data.some.subfield 或 this.data.some 被改变时触发
      console.log(subfield === this.data.some.subfield); // true
    },
    "arr[12]"(arr12) {
      // this.data.arr[12] 或 this.data.arr 被改变时触发
      console.log(arr12 === this.data.arr[12]);// true
    },
    "some.field.**"(field) {
      // this.data.some.field 或其下任何子数据字段或this.data.some 被改变时触发
      console.log(field === this.data.some.field);// true
    },
    "**"(field) {
      // 每次数据被改变时都触发
      console.log(field === this.data);// true
    },
  },
  attached() {
    // 这样会触发 some.field.** 的 observer
    this.setData({
      "some.field": {
        /* ... */
      },
    });
    // 这样也会触发 some.field.** 的 observer
    this.setData({
      "some.field.xxx": {
        /* ... */
      },
    });
    // 这样还是会触发 some.field.** 的 observer
    this.setData({
      some: {
        /* ... */
      },
    });
});

Bug & Tip

  • Tip: 如果在数据监听器函数中使用 setData 设置本身监听的数据字段,可能会导致死循环,需要特别留意。
点击纠错
该文档是否对你的开发有所帮助?
有帮助
没帮助
该文档是否对你的开发有所帮助?
有帮助
没帮助