代码之家  ›  专栏  ›  技术社区  ›  JW.

如何根据另一个值的变化来改变一个可观察的值?

  •  3
  • JW.  · 技术社区  · 7 年前

    假设我有两个黑帮的目标 @observable 领域:

    class Address {
      @observable country
      @observable city
    }
    

    当其中一个改变时,我想调用一个改变另一个的函数。例如,当 country 更改,我可能想清除 city 如果它的价值对新国家无效。

    有好的模式吗?

    我想我用不了 autorun . 因为我试图改变一个可观测的值 enforceActions 打开,我需要换一个 action . 但这会抛出一个错误“autorun不接受操作,因为操作是不可跟踪的”:

    autorun(action(() => {
        if (this.country === 'US' && this.city === 'Paris') this.city = '';
    }));
    

    我知道我可以加一个 @computed 函数返回 城市 或者一个新值。但是 城市 仍然在那里,当 国家 换回来。我不想这样,我想永久改变 城市 .

    @computed get realCity() {
        if (this.country === 'US' && this.city === 'Paris') return '';
        return this.city;
    }
    
    4 回复  |  直到 7 年前
        1
  •  3
  •   Tholle    7 年前

    你可以用 observe 观察构造器中的对象,并在国家更改时重置城市。

    实例(例) JSBin )

    class Address {
      @observable country = 'Sweden';
      @observable city = 'Stockholm';
    
      constructor() {
        observe(this, (change) => {
          if (change.name === 'country') {
            // Put your logic for changing the city here
            this.city = '';
          }
        });
      }
    }
    
    const address = new Address();
    
    console.log(`${address.country}, ${address.city}`);
    address.country = 'Spain';
    console.log(`${address.country}, ${address.city}`);
    
        2
  •  1
  •   Jason Mullings    7 年前

    此任务可以通过存储构造函数中初始化的“when”进程完成:

    class store(){
        constructor(){
         when (){
          ()=>{(this.country === 'US' && this.city === 'Paris')}
          ()=>{ this.city = ''}
        } 
      }
    } 
    

    完整且有文件证明的解释如下: https://mobx.js.org/refguide/when.html

        3
  •  1
  •   Kev    7 年前

    我认为你应该换个角度来看待你的问题。

    我问自己的问题是:你难道不能做点什么来避免你所面临的问题吗?

    为什么一开始就允许这种情况发生?

    • 如果设置了国家:请为该国家创建城市子集。
    • 如果一个城市被建立,而这个国家发生了变化,那就同时解除这个城市的治安。

    对于mobx特定的模式,这部分文档很有用:

    经验法则是:如果有一个函数应该自动运行,但不会产生新值,请使用autorun。对其他所有内容使用computed。自动运行是为了启动效果,而不是为了产生新的值。 Mobx docs

        4
  •  0
  •   Yoav Schniederman    6 年前
    observe(state, "country", ({ oldValue, newValue }) => this.handleCountryChange(oldValue, newValue));
    
    
    handleCountryChange = (oldValue, newValue) => {}