Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mobx';asFlat'';作为参考';没有按预期工作_Javascript_Ecmascript 6_Mobx_Ecmascript Next - Fatal编程技术网

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系列”}
  • 为什么bmw.config.model='5系'的反应不触发??。创建可观察对象时存在的对象属性是否被观察到更改
  • configAsReference
    的行为符合预期,仅当引用发生更改时才触发更改;因为该反应仅在
    bmw.configAsReference={swoord:'true'}
    上触发,这是一个引用更改
  • 只有当数据函数的返回值发生变化时,才会触发反应。默认比较只会执行
    this.colors===this.colors
    ,因此效果不会运行。尝试从数据函数返回
    this.colors.length

  • 出于性能原因,Mobx将在“事务”中批处理更新,因此在同一代码块中发生多个更改时,您不一定会看到每次更改后运行的反应

  • 通常,当您将元素添加到可观察数组中时,新元素本身就是可观察的。使用
    asFlat
    将禁用此行为,但当数组元素只是字符串时,将无法察觉

  • 我猜您只是查看在控制台中记录的扩展对象,它可能显示对象的当前值,而不是记录时对象的值。尝试记录各个键,您将看到记录时的值

  • 与问题(1)的问题相同。简单的比较不会显示任何更改-更新返回
    this.config.model
    的数据函数,您应该会看到一个反应

  • 这不是问题

  • 我有一些好消息
    asReference
    asFlat
    在较新版本中消失,但等同于
    observable.ref
    observable.shall
    。有关更多信息,请参阅