Как получить Mobx.autorun, чтобы предотвратить срабатывание в конструкторе класса?

В этом классе я использую инициализированное логическое состояние для выполнения Mobx.autorun. В противном случае «это» не присваивается полностью и приводит к ошибкам. Есть ли другой/более чистый способ сделать это?

class GameMaster{

  private _initialized:boolean = false;
  private _store:IDomainStore;
  private _moveDisposer:Lambda;

  /**
   *
   * @param store - client or server store
   */
    constructor(store:IDomainStore){
        this._store = store;
        console.log(this._store);
        //todo abstract services to decouple client device from GameMaster because it is also used on the server.
        this._moveDisposer = autorun(()=>{
          // prevent firing in the constructor
          if(this._initialized) {
            this.present(
              <IIntent>{
                fromId: 'GeoLocation.service',
                toIds: [Meteor.userId()],
                wish: actions.playerActions.types.CHANGE_PLAYER_GEO_COORDINATES,
                data: [System.GeolocationService.coordinates.lng, System.GeolocationService.coordinates.lat]
            });
          }
        });
        this._initialized = true;
      }

    public present(intent:IIntent):boolean{
      ...
    }
 ...
}

Это моя наблюдаемая в другом файле:

 @observable coordinates = {
    lng:0,
    lat:0
  };

person dagatsoin    schedule 04.05.2016    source источник
comment
Можете ли вы указать, какие переменные оформлены как наблюдаемые? Я ожидаю, что автозапуск вообще не сработает в вашей текущей настройке.   -  person mweststrate    schedule 04.05.2016
comment
И coordinates, вероятно, действительно срабатывает во время построения или, может быть, автозапуск запускается один раз для целей инициализации?   -  person dagatsoin    schedule 04.05.2016


Ответы (1)


Я думаю, что это хороший подход к проблеме, однако инициализированное поле также должно быть наблюдаемым. В противном случае изменение _initialized не приведет к повторному запуску автозапуска.

Но в этом случае я не уверен, чего именно инициализированная переменная достигает в вашем, потому что ваш первый оператор после автозапуска должен установить для инициализации значение true?

Так что я не совсем уверен, чего вы хотите добиться: отложить вызов автозапуска/present до конца конструктора или пропустить первый вызов present?

Обновленный ответ

Если вы хотите предотвратить побочный эффект (в данном случае отправку present), для этого есть простой шаблон. Подсказка заключается в том, чтобы убедиться, что вы вычисляете любое значение, необходимое для побочного эффекта, но не запускаете побочный эффект самостоятельно. Итак, в вашем примере это будет выглядеть

constructor(store:IDomainStore){
    let firstRun = true;
    this._moveDisposer = autorun(()=>{
        // make sure all information is tracked
        const presenceInfo = <IIntent>{
            fromId: 'GeoLocation.service',
            toIds: [Meteor.userId()],
            wish: actions.playerActions.types.CHANGE_PLAYER_GEO_COORDINATES,
            data: [System.GeolocationService.coordinates.lng, System.GeolocationService.coordinates.lat]
        }
        // but prevent the side effect in the first run
        if(!firstRun) {
            this.present(presenceInfo);
        } else {
            firstRun = false;
        }
    });
  }

(обратите внимание, что флаг может больше не понадобиться в будущем, так как существует существующее предложение передать параметр firstRun автозапускаемой функции).

person mweststrate    schedule 04.05.2016
comment
Я хочу, чтобы автозапуск не запускал свою функцию без видимых изменений. Поскольку в present() используются некоторые переменные экземпляра, которые нельзя использовать до конца вызова конструктора. - person dagatsoin; 04.05.2016
comment
Поведение автозапуска заключается в запуске после того, как даже его зависимости не изменились. Не является? - person dagatsoin; 04.05.2016
comment
Я имею в виду при инициализации. - person dagatsoin; 04.05.2016
comment
Исправление: если я установлю _initialized в качестве наблюдаемого, я буду работать с той же проблемой, что и автозапуск, который будет запущен до окончания вызова конструктора. Я просто подожду, пока сервис пришлет еще одну смену координат. - person dagatsoin; 04.05.2016
comment
умная! Я был близок. Спасибо. Хотя я думаю, что все-таки искал предложение firstRun. - person dagatsoin; 04.05.2016