2016-03-30 24 views
3

Angenommen, ich versuche, die Elm-Architektur zu folgen und meinen Workflow in User s und Invoice s zu teilen, während StartApp verwendet wird.Kommunikation zwischen Komponenten in Elm

Benutzer haben Rechnungen, aber sie müssen sich anmelden, um auf sie zugreifen zu können.

Das Modell wie etwas in dieser Richtung sehen kann:

type Model 
    = NotLoggedIn Credentials 
    | LoggedIn RealName (Maybe Invoices) 

type alias State = 
    { login : Model 
    , notification : ...... 
    , ...... 


type alias Invoices = { invoices: List Invoice, ...... } 

Benutzer-Modul hat Aktionen:

type Action 
    = Login (Result Http.Error String) 
    | Logout 
    | Submit 
    ... 

und Update-Funktion:

update : Action -> Model -> (Model, Effects Action, Notification) 
update action user = 
    case (action, user) of 
     (Login res, _) -> 
     case res of 
      Ok name -> 
       (LoggedIn name Nothing, Effects.none, Info "Welcome!") 
    ... 

springe ich die Details der Authentifizierung ist alles gut. Der interessante Teil ist Login Aktion. Das Tupel wird auf die step Funktion in main gesendet:

step : Action -> State -> (State, Effects Action) 
step action state = 
    case action of 
     UserAction a -> 
     let (newstate, ef, n) = User.update a state.login 
     in ({ state | login = newstate, notification = n }, Effects.map UserAction ef) 
     InvoiceAction a -> ...... 

So hat der Benutzer angemeldet Als nächstes werden wir einige init Aktion im Invoice Modul aufgerufen werden soll..

Aber wie soll das richtig gemacht werden? Wie initiiere ich die Aktion Invoice um die Verkapselung zu erhalten? Soll ich etwas anderes als Effects.none zurückgeben?

Antwort

3

Dies könnte ein Fall sein, der durch unterschiedliche Modellierung der Daten Ihrer App gelöst werden könnte.

So wie ich es verstehe, haben Sie Aktionen, die als Benutzer und Aktionen erfordern, die keinen Benutzer erfordern. Die InvoiceAction scheint mir, dass sie zur UserAction gehören sollte.

So konnten Sie

type MainAction = UserAction UAction | NonUserAction NonUAction 

type UAction = AuthAction Credentials | InvoiceAction Invoice.Action 

Das Benutzermodell beide Details Login haben würde kapseln und Rechnungsdetails. Und dann, nach einer erfolgreichen Anmeldung, könnten Sie zu einer InvoiceAction umleiten.

update action model = 
    case action of 
    AuthAction credentials -> 
     let 
     (isLoggedIn, notifications) = Authentication.check credentials 
     model' = { model | credentials = credentials, notifications = notifications} 
     in 
     if isLoggedIn 
     then update (Invoice.initialize model'.credentials) model' 
     else (model', Effects.none) 

    InvoiceAction act -> 
     let 
     (invoices, fx) = Invoice.update model.credentials act model.invoices 
     in 
     ({model | invoices = invoices}, Effects.map InvoiceAction fx) 

die eigentliche Aktion wird durch den Rechnungsmodul über eine Funktion initialize mit einer Signatur wie initialize: Credentials -> Action versehen. Dies wird getan, um die Einkapselung aufrechtzuerhalten. Das Benutzermodul muss nicht über bestimmte Rechnungsaktionen Bescheid wissen, nur dass es einen gibt, der sich auf die Initialisierung bezieht und es über diese Funktion erhalten kann.

Bitte beachten Sie auch, dass ich die Update-Signatur vereinfacht und die Benachrichtigungen innerhalb des Modells verschoben habe. Dies ist eine persönliche Vorliebe, da ich Benachrichtigungen als nichts Besonderes sehe. Sie sind wie alle anderen Daten im Modell. Wenn es sich bei den Benachrichtigungen um Aufgaben handelt, die über eine benutzerdefinierte StartApp in einen Port geroutet werden und von einem JS-Mechanismus angezeigt werden, kann es sinnvoll sein, sie in der Rückgabe zu belassen.

2

Ein Ansatz wird sein:

  • ein Postfach in der Komponente Mutter erstellen
  • Geben Sie die Adresse dieses Postfach User Update
  • Benutzer Update gibt einen Effekt, der eine Nachricht an diese Adresse sendet
  • Nach einer Nachricht diese Mailbox empfangen löst eine Aktion aus, die
zu Invoice fließt

Dieses Kapitel in Ulm-Tutorial zeigt dieses Muster http://www.elm-tutorial.org/090_showing_errors/flow.html

+0

Vielen Dank für wertvolle Einblicke. – punund

Verwandte Themen