2016-04-27 3 views
1

Ich versuche Mobx die Autorun zu bekommen richtig zu arbeiten.Mobx Autorun in der Praxis

Mein Anwendungsfall ist ich ein Modell, das ich serialisiert mag (oder zu entwässern), wenn es geändert wird und diese Informationen an den Daten eines anderen Modells hinzufügen. Das bringt mir rudimentäre Zeitreisen von Modellstaaten. Beide sind Observable.

Edit: Idea in Modell Trennung ist, dass man Daten der App-Modell und andere sollen vollständig separate Bibliothek sein, die ich aus der App nutzen könnte. Ich muss regelmäßig die Änderungen in der App verfolgen, aber die Benutzeroberfläche für das Status-Tool auf derselben Seite anzeigen.

Nun Autorun scheint seine eigenen Schlüsse zu machen, was ich Tracking tatsächlich. Wenn ich die Modellinstanz in die Instanziierung des Modells verschoben habe, wurde Autorun nicht mehr aufgerufen, wenn Änderungen vorgenommen wurden. Wenn die Modellinstanz auf der obersten Modulebene erstellt wurde, funktionierte sie wie erwartet. Dies war, als ich nur eine Eigenschaft des Beobachtungsmodells änderte (dasjenige, das bei jedem Autorun-Aufruf geändert wird). Als ich im beobachtenden Modell versuchte, zwei Dinge auf einmal zu ändern, wurde nun auch Autorun für diese Änderungen aufgerufen, was zu einem endlosen Zyklus führte (den Mobx erwischte).

Ich möchte wissen, wie ich ausdrücken kann, was ich mit der Autorun-Funktion trackere, expliziter sein, oder ob es andere Möglichkeiten gibt, Modelländerungen zu verfolgen und andere Modelle zu aktualisieren, wenn etwas passiert.


Bearbeiten mit Codebeispiel.

Das ist, was ich tat (stark vereinfacht):

class DataModel { 
    @observable one_state = null; 
} 

class StateStore { 
    @observable states = []; 
} 

let data = new DataModel(); 
let store = new StateStore(); 

autorun(() => { 
    store.states.push(data.one_state); 
    console.log("new data", toJSON(store.states)); 
}); 

data.one_state = "change 1"; 
data.one_state = "change 2"; 

Und das schafft zirkuläre Abhängigkeit, da Autorun für sowohl Änderung ursprünglichen Datenmodells und der daraus resultierenden Änderung Speicher aufgerufen wird, während ich nur daran interessiert bin in der Verfolgung von Änderungen an ersterem.


Bearbeiten mit Arbeitsergebnis:

class DataModel { 
    @observable one_state = null; 
} 

class StateStore { 
    @observable states = asFlat([]); 
} 

let data = new DataModel(); 
let store = new StateStore(); 

autorun(() => { 
    store.states.push(data.one_state); 
}); 

data.one_state = "change 1"; 
data.one_state = "change 2"; 

Wie pro @mweststrate Antwort, mit asFlat mit Store Staaten Variable und die Protokollierung von Autorun entfernt brach das Problem Zyklus.

+0

Nach weiterem Lernen gelang es mir, das Autorun mit wenig Indirektion zu arbeiten. Laut Dokumentation ist Autorun für "reaktive Funktion, die niemals Beobachter selbst haben wird". Ich dachte, dass die Reaktion auf das Modell beschränkt ist, das ich beobachte, nicht alle Modelle in der gleichen App. Autorun erkennt sowohl mein Datenmodell als auch das Zustandsmodell und bemerkt Änderungen in beiden. Warum es in einigen Fällen funktioniert und nicht in anderen, ist etwas verwirrend. Ich muss mehr suchen, um den richtigen Weg für diesen Anwendungsfall zu finden. – jarpineh

+0

Ich habe dieses Projekt gefunden: https://github.com/AriaFallah/mobx-store Ich benutze scheinbar Autorun auf falsche Weise hier. Ich habe versucht, "berechnet" und seine Beobachtungsmethode zu verwenden, aber das scheiterte noch schneller. Es scheint, dass ich meinen Ansatz überdenken muss. Above-Store-Implementierung verwendet Funktion beobachten direkt und sieht wirklich einfach aus (obwohl es verfolgen muss, wann Änderungen vorgenommen werden). – jarpineh

Antwort

4

Es ist ein bisschen schwierig, diese Frage ohne echten Code zu beantworten. Könnten Sie etwas Code teilen? Aber beachte, dass MobX am besten funktioniert, wenn du eine kleine Gedankenverschiebung machst: anstatt zwingend zu sagen "wenn X passiert, sollte Y geändert werden", ist es besser zu sagen "Y kann von X abgeleitet werden". Wenn Sie in diese Richtung denken, wird MobX wirklich anfangen zu glänzen.

Statt zwei beobachtbaren Modelle zu haben, denke ich, eine von ihnen eine Ableitung des anderen sein sollte (von der Tat berechnet unter Verwendung). Ist das sinnvoll? Sonst fühlen Sie sich frei auf Ihre Frage ein bisschen mehr zu erarbeiten :)

Edit:

Ok danke für den Code. Sie sollten die Protokollanweisung entfernen, um das Schleifen zu vermeiden. Derzeit protokollieren Sie das Statusmodell, so dass jedes Mal, wenn es sich ändert, das Autorun ausgeführt wird, indem das erste Element hinzugefügt wird (wieder!), Das stateModel geändert wird usw.

Zweitens bin ich mir nicht sicher, ob die Zustandsliste sein sollte beobachtbar, aber zumindest sollte sein Inhalt nicht beobachtbar sein (da es sich um eine Momentaufnahme handelt und die Daten pro Zustand sich nicht ändern sollten).Um dies auszudrücken, können Sie den Modifikator asFlat verwenden, der darauf hinweist, dass die Statusauflistung nur oberflächlich beobachtbar sein sollte: @observable states = asFlat([]).

Beantwortet das Ihre Frage?

+0

Idee ist es, einen Speicher für frühere Zustände zu haben, die vom App-Zustand abgeleitet sind. Die Umsetzung scheint hart zu sein. Ich muss die Modelle getrennt halten, weil ich möchte, dass die App nicht merkt, dass das Tool so weit wie möglich funktioniert. Das beste Szenario besteht darin, neue Daten aus dem App-Modell zu erhalten, wenn Reaktionen stattfinden, und unabhängig davon den Status des Status-Tools abzuleiten. – jarpineh

+0

Mobx-Shop, den ich oben verlinkt benutze, beobachten Funktion: https://github.com/AriaFallah/mobx-store/blob/master/src/index.js#L85 Dies sieht den Weg, um für mich zu gehen. Ich kann den Mobx-Store allerdings nicht nutzen, da ich die App-Seite nicht auf eine bestimmte API zwingen möchte. – jarpineh

+0

Haben Sie https://github.com/mobxjs/mobx-reactive2015-demo überprüft? Es verfolgt die Zustände der Geschichten auch in einer separaten Zustandsgeschichte und verwendet dafür strukturelles Teilen. Für eine Erklärung, wie das funktioniert: http://mobxjs.github.io/mobx/refguide/create-transformer.html – mweststrate