2016-05-04 4 views
2

In dieser Klasse verwende ich einen initialisierten bool-Zustand, um die Ausführung von Mobx.autorun zu erreichen. Otherwize 'this' ist nicht vollständig zugewiesen und führt zu Fehlern. Gibt es einen anderen/saubereren Weg, dies zu tun?Wie kann Mobx.autorun ausgegeben werden, um das Feuern im Klassenkonstruktor zu verhindern?

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{ 
     ... 
    } 
... 
} 

Das ist mein beobachtbaren in einer anderen Datei:

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

Können Sie angeben, welche Variablen als beobachtbar dekoriert sind? Ich würde erwarten, dass das Autorun überhaupt nicht in Ihrem aktuellen Setup feuert. – mweststrate

+0

Und 'Koordinaten' werden wahrscheinlich während der Konstruktion abgefeuert oder vielleicht wird Autorun einmal zur Initialisierung ausgeführt? – dagatsoin

Antwort

3

Ich denke, das ist eine feine Annäherung an das Problem, aber das initialisierte Feld sollte auch erkennbar sein. Andernfalls führt das Ändern von _initialized nicht dazu, dass das Autorun erneut ausgeführt wird.

Aber in diesem Fall bin ich nicht sicher, was die initialisierte Variable genau in Ihrem erreicht, weil Ihre erste Anweisung nach dem Autorun auf True initialisiert werden soll?

So bin ich nicht ganz sicher, was Sie erreichen sollen: verschieben Sie den Autorun/present Aufruf an das Ende des Konstruktors, oder um den ersten present Aufruf zu überspringen?

aktualisiert Antwort

Wenn Sie die Nebenwirkung verhindern wollen (present in diesem Fall sendet) gibt es ein einfaches Muster dafür. Der Hinweis ist, dass Sie jeden Wert berechnen, der für den Nebeneffekt benötigt wird, aber den Nebeneffekt nicht selbst auslösen. Also in Ihrem Beispiel würde so aussehen

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; 
     } 
    }); 
    } 

(beachten Sie, dass das Flag möglicherweise nicht mehr in der Zukunft benötigt werden, da es ein bestehendes proposal ist ein param firstRun an die autorunned Funktion zu übergeben).

+0

Ich möchte verhindern, dass Autorun seine Funktion ohne beobachtbare Änderung auslöst. Da present() einige Instanzvariablen verwenden, die vor dem Ende des Konstruktoraufrufs nicht verwendbar sind. – dagatsoin

+0

Autorun-Verhalten soll einmal ausgeführt werden, selbst wenn seine Abhängigkeiten nicht geändert wurden. Ist nicht? – dagatsoin

+0

Ich meine bei der Initialisierung. – dagatsoin