Observable Arrays

和对象相似,使用observable也可以使数组变成可观察的,其还是通过递归工作实现的,所以所有(将来有)的数组值都是可被观察的。

import {observable, autorun} from "mobx";

var todos = observable([
    { title: "Spoil tea", completed: true },
    { title: "Make coffee", completed: false }
]);

autorun(() => {
    console.log("Remaining:", todos
        .filter(todo => !todo.completed)
        .map(todo => todo.title)
        .join(", ")
    );
});
// Prints: 'Remaining: Make coffee'

todos[0].completed = false;
// Prints: 'Remaining: Spoil tea, Make coffee'

todos[2] = { title: 'Take a nap', completed: false };
// Prints: 'Remaining: Spoil tea, Make coffee, Take a nap'

todos.shift();
// Prints: 'Remaining: Make coffee, Take a nap'

由于 ES5 中原生数组的限制(array.observe仅在 ES7 中可用, 并且数组无法扩展),observable将参数提供的数组进行克隆替代原始的那个。在实践中,这些数组工作的和原生的数组一样好,并且其支持所有原生方法,包括索引分配,up-to 和包括数组的长度。

请记住无论如何Array.isArray(observable([]))都将返回false,所以当你需要传递一个可观察的数组给外部库时,最好使用array.slice() 创建一个其浅拷贝在传递给其它库或者内置函数 使用(这是最好的做法)。换句话说,Array.isArray(observable([]).slice())将会返回true

和函数内置实现的sortreverse不同,observableArray.sort 和 reverse 不会改变数组的结构, 只会返回一个 sorted / reversed 的克隆。

除了所有的内置函数,下面的方法对可观察的数组来说也是非常有用的:

  • intercept(interceptor),它可以作用于数组以拦截任何改变前的状态,具体请参阅observe & intercept
  • observe(listener, fireImmediately? = false)监听数组的改变。其回调会在数组拼接或数组变化时接收参数 :(。它将返回一个处理函数以停止监听。
  • clear() 从数组中删除
  • replace(newItems) 用一个新的条目替换数组中所有存在的条目。
  • find(predicate: (item, index, array) => boolean, thisArg?), fromIndex?) 基本上和ES7的Array.find提议相同,除了附加的fromIndex
  • remove(value)按值移除数组中的单条条目。如果找到它们并移除时将会返回true
  • peek() 返回一个包含所有值的并可以安全的传递给其它库使用的数组,就像slice()一样。和slice不同,peek并不会创建一个新的副本。如果你确定要以只读方式使用数组,你可以在对对性能要求较高的应用中使用它。在性能关键部分,建议也使用可观察的数组。

observable.shallowArray(values)

任何分配给可观察数组的值都将都通过 observable 使其变成客观差的。 创建一个浅数组可以取消这些行为并按照原样存储。有关此机制的详细信息可参阅 modifiers

Name 参数

observable.arrayobservable.shallowArray 都有第二个参数, 这个参数被当做如 spy 或者 MobX 开发工具的调试名称。