Observable 对象

Usage observable.object(props, decorators?, options?)

如果把一个普通的 JavaScript 对象传递给 observable 方法,对象的所有属性都将被拷贝至一个克隆对象并将克隆对象转变成可观察的。(普通对象是指不是使用构造函数创建出来的对象,而是以 Object 作为其原型,或者根本没有原型。)默认情况下,observable 是递归应用的,所以如果对象的某个值是一个对象或数组,那么该值也将通过 observable 传递。

  1. import {observable, autorun, action} from "mobx";
  2. var person = observable({
  3. // observable 属性:
  4. name: "John",
  5. age: 42,
  6. showAge: false,
  7. // 计算属性:
  8. get labelText() {
  9. return this.showAge ? `${this.name} (age: ${this.age})` : this.name;
  10. },
  11. // 动作:
  12. setAge(age) {
  13. this.age = age;
  14. }
  15. }, {
  16. setAge: action
  17. });
  18. // 对象属性没有暴露 'observe' 方法,
  19. // 但不用担心, 'mobx.autorun' 功能更加强大
  20. autorun(() => console.log(person.labelText));
  21. person.name = "Dave";
  22. // 输出: 'Dave'
  23. person.setAge(21);
  24. // 等等

当使对象转变成 observable 时,需要记住一些事情:

  • 只有普通的对象可以转变成 observable 。对于非普通对象,构造函数负责初始化 observable 属性。要么使用 @observable 注解,要么使用 extendObservable 函数。
  • 属性的 getter 会自动转变成衍生属性,就像 @computed 所做的。
  • observable 是自动递归到整个对象的。在实例化过程中和将来分配给 observable 属性的任何新值的时候。Observable 不会递归到非普通对象中。
  • 这些默认行为能应对95%的场景,但想要更细粒度的控制,比如哪些属性应该转变成可观察的和如何变成可观察的,请参见装饰器
  • 传入 { deep: false } 作为第三个参数可以禁用属性值的自动转换
  • 传入 { name: "my object" } 为本对象赋予友好的调试名称
  • [MobX 4 及以下版本] 当通过 observable 传递对象时,只有在把对象转变 observable 时存在的属性才会是可观察的。稍后添加到对象的属性不会变为可观察的,除非使用 setextendObservable