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 }); // 表示任何将来的值都不会自动转成observable
observable.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 数组或对象上引入新的属性。