Javascript Mobx';asFlat'';作为参考';没有按预期工作
我们正在我们的一个项目中使用,我看到在代码中频繁使用Javascript Mobx';asFlat'';作为参考';没有按预期工作,javascript,ecmascript-6,mobx,ecmascript-next,Javascript,Ecmascript 6,Mobx,Ecmascript Next,我们正在我们的一个项目中使用,我看到在代码中频繁使用asFlat和asReference。根据我的理解,asReference仅在引用更改时触发更改,而不是在对象上的任何属性更改时触发更改。相反,Mobx将跟踪标记为可观察的对象的所有属性(假定这些属性在对象创建期间存在)。但在下面的代码中,我看不到两者之间的行为有任何变化 类似地,asFlat允许观察属性本身,但不允许观察其任何子级。这意味着向标记为asFlat的数组添加新值不会触发更改,但更改数组的引用会触发更改。但是,在下面的代码中,两个数
asFlat
和asReference
。根据我的理解,asReference
仅在引用更改时触发更改,而不是在对象上的任何属性更改时触发更改。相反,Mobx将跟踪标记为可观察的对象的所有属性(假定这些属性在对象创建期间存在)。但在下面的代码中,我看不到两者之间的行为有任何变化
类似地,asFlat
允许观察属性本身,但不允许观察其任何子级。这意味着向标记为asFlat
的数组添加新值不会触发更改,但更改数组的引用会触发更改。但是,在下面的代码中,两个数组的行为完全相同。为什么会这样
另外,由于两者看起来相似,asReference
和asFlat
之间有什么区别
const {observable, asFlat, asReference, reaction} = mobx;
class Car {
constructor() {
reaction(() => this.colors, () => console.log('colors changed: ',this.colors));
reaction(() => this.colorsAsFlat, () => console.log('colorsAsFlat changed: ',this.colorsAsFlat));
reaction(() => this.config, () => console.log('config changed: ',this.config));
reaction(() => this.configAsReference, () => console.log('configAsReference changed: ',this.configAsReference));
}
@observable colors = [];
@observable colorsAsFlat = asFlat([]);
@observable config = {model : '7 Series'};
@observable configAsReference = asReference({model : '7 Series'});
}
const bmw = new Car();
bmw.colors.push('Red');
bmw.colors[1] = 'Gray';
bmw.colors = ['Black'];
bmw.colors.push('Blue');
bmw.colorsAsFlat.push('Red');
bmw.colorsAsFlat[1] = 'Gray';
bmw.colorsAsFlat = ['Black'];
bmw.colorsAsFlat.push('Blue');
console.log("Initial Config: ", bmw.config);
bmw.config.model = '5 Series';
bmw.config.autopilot = 'true';
bmw.config = { sunroof : 'true'};
bmw.configAsReference.model = '5 Series';
bmw.configAsReference.autopilot = 'true';
bmw.configAsReference = { sunroof : 'true'};
reaction
仅用于跟踪可观测属性的变化,并在可观测属性发生变化时记录其变化。是一把同样的小提琴。观察控制台输出中的此代码
上述代码中的问题:
为什么bmw.colors.push('Red')
和bmw.colors[1]='Gray'
没有引发变化(反应)
bmw.colors=['Black']
引发了反应,但为什么colors
数组在日志中也包含'Blue',而'Blue'被分配在'Black'之后
colorsaflat
在与colors
相同的更改时触发,即使它被声明为asFlat
。因此,它应该只在bmw.colorsAsFlat=['Black']
上启动,因为它是一个参考更改(确实如此),但它也意外地包含了“蓝色”。为什么会这样
console.log
语句之后分配这两个属性时,日志bmw.config
会打印初始配置:{autopilot:“true”,model:“5系列”}
configAsReference
的行为符合预期,仅当引用发生更改时才触发更改;因为该反应仅在bmw.configAsReference={swoord:'true'}
上触发,这是一个引用更改this.colors===this.colors
,因此效果不会运行。尝试从数据函数返回this.colors.length
asFlat
将禁用此行为,但当数组元素只是字符串时,将无法察觉this.config.model
的数据函数,您应该会看到一个反应asReference
和asFlat
在较新版本中消失,但等同于observable.ref
和observable.shall
。有关更多信息,请参阅