MobX Обновление декорированного объекта в свойстве украшенного массива не вызывает реакции - PullRequest
0 голосов
/ 01 мая 2019

Я написал прототип 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 ged:

enter image description here

Однако, когда я пытаюсь:

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

Ничего не происходит; // MobX не реагирует !!

Я не знаю, что я могу сделать, чтобы MobX отреагировал на это, так как он был поднят из компонента React.

1 Ответ

1 голос
/ 02 мая 2019

Кажется, вы неправильно понимаете, как работает автозапуск.autorun подписывается на изменения значений переменных, на которые ссылается функция.

Что происходит

Здесь ваша функция автозапуска наблюдает payRates и currentPayRate.

В первый раз вы изменяете payRates и currentPayRate (поскольку вы изменяете payRateIndex, обновляется вычисленное свойство currentPayRate).

-> автозапуск отреагировал.

Во второй раз вы изменяете свойство элемента в массиве payRates, а не само значение this.payRates, это все тот же массив.Таким образом, payRates не изменился, и currentPayRate.

-> автозапуск не реагирует.

Подробнее об автозапуске

Автозапуск не будет подписываться на "вложенные"элементы массива.Для более подробной информации, вы можете прочитать это: Следите за изменениями вложенных объектов / массивов

...