observable 对象
用法
observable(value)@observable classProperty = value
Observable 值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射。 匹配类型应用了以下转换规则,但可以通过使用调节器进行微调。请参见下文。
- 如果 value 是ES6的
Map: 会返回一个新的 Observable Map。如果你不只关注某个特定entry的更改,而且对添加或删除其他entry时也做出反应的话,那么 Observable maps 会非常有用 - 如果 value 是数组,会返回一个 Observable Array。
- 如果 value 是没有原型的对象,那么对象会被克隆并且所有的属性都会被转换成可观察的。参见 Observable Object。
- 如果 value 是有原型的对象,JavaSript 原始数据类型或者函数,会返回一个
observable.box(value)。MobX 不会将一个有原型的对象自动转换成可观察的,因为这是它构造函数的职责。在构造函数中使用extendObservable或者在类定义中使用@observable。 - 如果 value 是有原型的对象,JavaSript 原始数据类型或者函数,
observable会抛出。如果想要为这样的值创建一个独立的可观察引用,请使用observable.box(value)代替。MobX 不会将一个有原型的对象自动转换成可观察的,因为这是它构造函数的职责。在构造函数中使用extendObservable或在类定义上使用@observable/decorate。
乍看之下,这些规则可能看上去很复杂,但实际上实践当中你会发现他们是非常直观的。
const map = observable.map({ key: "value"});map.set("key", "new value");const list = observable([1, 2, 4]);list[2] = 3;const person = observable({firstName: "Clive Staples",lastName: "Lewis"});person.firstName = "C.S.";const temperature = observable.box(20);temperature.set(25);
api
observable.object(props, decorators?, options?) 或 observable({})
创建一个可被监听的对象
注意,属性映射中的任意 getters 都会转化成计算属性。
observable.array(values?) 或 observable([]) 创建一个可被监听的数组
observable.array(values, { deep: false })observable.array(values, { name: "my array" })
除了所有内置函数,observable 数组还可以使用下面的好东西:
intercept(interceptor)- 可以用来在任何变化作用于数组前将其拦截。参见 observe & interceptobserve(listener, fireImmediately? = false)- 监听数组的变化。回调函数将接收表示数组拼接或数组更改的参数,它符合 ES7 提议。它返回一个清理函数以用来停止监听器。clear()- 从数组中删除所有项。replace(newItems)- 用新项替换数组中所有已存在的项。find(predicate: (item, index, array) => boolean, thisArg?)- 基本上等同于 ES7 的Array.find提议。findIndex(predicate: (item, index, array) => boolean, thisArg?)- 基本上等同于 ES7 的Array.findIndex提议。remove(value)- 通过值从数组中移除一个单个的项。如果项被找到并移除的话,返回true。- [MobX 4 及以下版本]
peek()- 和slice()类似, 返回一个有所有值的数组并且数组可以放心的传递给其它库。
不同于 sort 和 reverse 函数的内置实现,observableArray.sort 和 observableArray.reverse 不会改变数组本身,而只是返回一个排序过/反转过的拷贝。在 MobX 5 及以上版本中会出现警告。推荐使用 array.slice().sort() 来替代。
observable.map(values, options?) 或 observable(new Map()) 创建一个可被监听的map
observable.map(values, { deep: false });observable.map(values, { name: "my array" });
下列 observable 映射所暴露的方法是依据 ES6 Map 规范:
has(key)- 返回映射是否有提供键对应的项。注意键的存在本身就是可观察的。set(key, value)- 把给定键的值设置为value。提供的键如果在映射中不存在的话,那么它会被添加到映射之中。delete(key)- 把给定键和它的值从映射中删除。get(key)- 返回给定键的值(或undefined)。keys()- 返回映射中存在的所有键的迭代器。插入顺序会被保留。values()- 返回映射中存在的所有值的迭代器。插入顺序会被保留。entries()- 返回一个(保留插入顺序)的数组的迭代器,映射中的每个键值对都会对应数组中的一项[key, value]。forEach(callback:(value, key, map) => void, thisArg?)- 为映射中每个键值对调用给定的回调函数。clear()- 移除映射中的所有项。size- 返回映射中项的数量。
以下函数不属于 ES6 规范,而是由 MobX 提供:
toJS()- 将 observable 映射转换成普通映射。toJSON(). 返回此映射的浅式普通对象表示。(想要深拷贝,请使用mobx.toJS(map))。intercept(interceptor)- 可以用来在任何变化作用于映射前将其拦截。参见 observe & intercept。observe(listener, fireImmediately?)- 注册侦听器,在映射中的每个更改时触发,类似于为 Object.observe 发出的事件。想了解更多详情,请参见 observe & intercept。merge(values)- 把提供对象的所有项拷贝到映射中。values可以是普通对象、entries 数组或者 ES6 字符串键的映射。replace(values)- 用提供值替换映射全部内容。是.clear().merge(values)的简写形式。observable.box(value)
observable.box(value)接收任何值并把值存储到箱子中。 使用.get()可以获取当前值,使用.set(newValue)可以更新值。
此外,还可以使用它的.observe方法注册回调,以监听对存储值的更改。 但因为 MobX 自动追踪了箱子的变化,在绝大多数情况下最好还是使用像mobx.autorun这样的 reaction 来替代。observable.box(scalar)返回的对象签名是:.get()- 返回当前值。.set(value)- 替换当前存储的值并通知所有观察者。intercept(interceptor)- 可以用来在任何变化应用前将其拦截。参见 observe & intercept。.observe(callback: (change) => void, fireImmediately = false): disposerFunction- 注册一个观察者函数,每次存储值被替换时触发。返回一个函数以取消观察者。参见 observe & intercept。change参数是一个对象,其中包含 observable 的newValue和oldValue。
observable.box(value, { deep: false }); // 表示任何将来的值都不会自动转成observableobservable.box(value, { name: "my array" }); // 设置一个名字,用于调试定位什么的很方便import {observable} from "mobx";const cityName = observable.box("Vienna");console.log(cityName.get());// 输出 'Vienna'cityName.observe(function(change) {console.log(change.oldValue, "->", change.newValue);});cityName.set("Amsterdam");// 输出 'Vienna -> Amsterdam'
extendObservable(target, properties, decorators?, options?)
ExtendObservable 用来向已存在的目标对象添加 observable 属性。 属性映射中的所有键值对都会导致目标上的新的 observable 属性被初始化为给定值。 属性映射中的任意 getters 都会转化成计算属性。decorators 参数用来重载用于指定属性的装饰器,类似于 decorate 和 observable.object 。
使用 deep: false 选项可使得新的属性变成浅的。也就是说,阻止它们的值自动转换成 observables 。
var Person = function(firstName, lastName) {// 在一个新实例上初始化 observable 属性extendObservable(this, {firstName: firstName,lastName: lastName,get fullName() {return this.firstName + " " + this.lastName},setFirstName(firstName) {this.firstName = firstName}}, {setFirstName: action});}var matthew = new Person("Matthew", "Henry");// 向 observable 对象添加 observable 属性extendObservable(matthew, {age: 353});Copy
注意: observable.object(object) 实际上是 extendObservable({}, object) 的别名。
注意: 类似于 extendObservable,decorate 用来为对象引入 observable 属性。不同之处在于 extendObservable 被设计为直接在目标实例上引入属性,其中 decorate 将它们引入原型; 可以直接将它传递给构造函数 (类),也可以将其作为其他人的原型。
注意: 不能使用 extendObservable 来为 observable 数组或对象上引入新的属性。
