MobX更新装饰数组属性中的装饰对象不会发出反应

时间:2019-05-01 15:27:04

标签: mobx

我为正在处理的薪资字段编写了一个React原型,现在我正尝试将其状态提升到域存储。现在,我只是想在控制台中测试响应,但是由于某种原因,当使用操作来更改该商店的可观察数组的字段时,响应不起作用。

代码

我有以下内容:

数据对象

class PayRate {
  /**
   * @param {number} taskId The id of the task. (-1 for all)
   * @param {Date} effectiveDate The date the payrate goes in effect.
   * @param {number} rate The rate of pay.
   */
  constructor(taskId, effectiveDate, rate) {
    this.TaskId = taskId || -1;
    this.EffectiveDate = effectiveDate ? new Date(effectiveDate) : new Date();
    this.Rate = rate || 0.00;
    this.OriginalObject = Object.assign({}, this);
  }

  /**
   * Gets a readable version of the effective date.
   * @returns {string} A -m/dd/yyyy representation of the effective date.
   */
  GetReadableDate() {
    return this.EffectiveDate.toLocaleDateString("en-US");
  }
  /**
   * Gets a one line description of the pay rate.
   * @returns {string} A string in the form of (date) - payrate.
   */
  GetDescription() {
    return `(${this.GetReadableDate()}) - $${this.Rate.toFixed(2)}`;
  }
  /**
   * Gets a one line description of the pay rate.
   * Does the exact same as GetDescription(), but is overload of Object.prototype.toString, which allows for stringification of Objects
   * @returns {string} A string in the form of (date) - payrate.
   */
  toString() {
    return `(${this.GetReadableDate()}) - $${this.Rate.toFixed(2)}`;
  }
  /**
   * Tells whether a pay rate was changed or not.
   * @returns {boolean} A boolean saying whether or not the pay rate was changed.
   */
  IsChanged() {
    if (this.EffectiveDate.getTime() !== this.OriginalObject.EffectiveDate.getTime()) {
      return true;
    }
    if (this.Rate != this.OriginalObject.Rate) {
      return true;
    }
    if (this._deleted) {
      return true;
    }
    return false;
  }
  /**
   * Reverts the changes back to the original.
   */
  RevertChanges() {
    Object.assign(this, this.OriginalObject);
  }
}

// mobx decorations
mobx.decorate(PayRate, {
  TaskId : mobx.observable,
  EffectiveDate : mobx.observable,
  Rate : mobx.observable,
})

域存储

class PayRatesStore { 
    constructor() { 
        this.payRates = [];

        this.payRateIndex = -1;

        this._dateString = '';

        this.payRateIndicesToDelete = [];

        mobx.autorun(() => {
            console.log(this.payRates)
            console.log(this.currentPayRate)
        })
    }

    // getters
    get currentPayRate() { 
        if ((this.payRates) && (this.payRates.length)) {
            return this.payRates[this.payRateIndex];
        }
        return new PayRate();
    }

    get dateString() { 
        if (!this._dateString) { 
            if (this.currentPayRate) { 
                return this.currentPayRate.GetReadableDate()
            }
            return "";
        }
        return this._dateString;
    }

    set dateString(str) { 
        this._dateString = str;
    }

    updateCurrentPayRateDate(dateString) { 
        // update _dateString
        this._dateString = dateString

        this.payRates[this.payRateIndex].EffectiveDate = new Date(dateString)
    }
}

mobx.decorate(PayRatesStore, {
    payRates : mobx.observable,
    payRateIndex : mobx.observable,
    _dateString : mobx.observable,
    payRateIndicesToDelete : mobx.observable,
    currentPayRate : mobx.computed,
    dateString : mobx.computed,
    updateCurrentPayRateDate : mobx.action.bound
})

设置PayRatesStore会引起我们期望的反应:

let payRate = new PayRate(1, "03/25/2019", 15.5),
  payRates = [ payRate ]
// create PayRatesStore
let payRatesStore = new PayRatesStore()
console.log("Passing data to pay rates store....")
  payRatesStore.payRates = payRates
  payRatesStore.payRateIndex = 0

使console.log符合以下条件:

enter image description here

但是,当我尝试时:

payRatesStore.updateCurrentPayRateDate('4/1/2019')

什么也没发生; // MobX没有反应!

我不知道如何使MobX对此做出反应,因为它是从React组件中提起的。

1 个答案:

答案 0 :(得分:1)

似乎您误解了自动运行的工作方式。 autorun订阅该函数中引用的变量值的更改。

发生了什么

在这里,您的自动运行功能正在观察payRatescurrentPayRate

第一次,您同时修改了payRatescurrentPayRate(因为您更改了payRateIndex,它更新了计算的属性currentPayRate)。

->自动运行发生反应。

第二次,您修改了payRates数组中的元素属性,而不是this.payRates本身的值,它仍然是同一数组。因此,payRates不变,currentPayRate也不变。

->自动运行没有反应。

有关自动运行的更多信息

自动运行不会订阅“嵌套的”数组元素。有关更多详细信息,您可以阅读以下内容:Watch for nested object/array changes