2016-06-02 14 views
4

Ich lese durch die Elm guide und ihre JavaScript interOp. Hier ist eine vereinfachte Version:Problem beim Verbinden von Ports und Abonnements

port module FooBar exposing (..) 

import Html exposing (..) 
import Html.Attributes exposing (..) 
import Html.App as Html 
import String 

main = 
    Html.program 
    { init = init 
    , view = view 
    , update = update 
    , subscriptions = subscriptions 
    } 

-- subscriptions 
port f :() -> Cmd msg 
port g : (Int -> msg) -> Sub msg 

subscriptions: Model -> Sub Msg 
subscriptions model = g Get 

-- MODEL 
type alias Model = { pt : Int } 

-- VIEW 
view: Model -> Html Msg 
view model = Html.text (toString model.pt) 

-- UPDATE 
type Msg = Ask | Get Int 

update: Msg -> Model -> (Model, Cmd msg) 
update msg model = 
    case msg of 
    Ask -> (model, f()) 
    Get x -> (Model x, Cmd.none) 

-- INIT 
init: (Model, Cmd Msg) 
init = (Model 0, f()) 

Die App wird anfänglich auf aber es sollte die Nachricht von JavaScript zu lesen und zu eingestellt werden. Es bleibt jedoch bei . Sind die Elm-Ports richtig eingerichtet?

<div id="foobar"></div> 
<script src="foo.js"></script> 
<script> 
    var node = document.getElementById("foobar"); 
    var app = Elm.FooBar.embed(node); 

    app.ports.f.subscribe(
    function(){ 
     var myValue = 1; 
     console.log(myValue); 
     app.ports.g.send(myValue); 
    } 
); 
</script> 

</body> 

Hier habe ich gesagt: elm-make foo.elm --output=foo.js

Die Tatsache, dass myValue Drucke zu trösten als schlägt der f() Hafen wurde genannt, aber der g() Port wird nie wieder oder behandelt geschickt richtig.

Antwort

3

Schwer zu sagen, ob dies eine Design-Entscheidung ist, aber init wird aufgerufen, bevor Html.App an allen Ports abonniert ist.

Daher f() von aufrufen wird keinen Effekt haben.

Ich benutze send Funktion, die eine Dummy-Aufgabe läuft und sendet immer Ask Nachricht, die den ausgehenden Port auslösen wird.

Betrachten Sie Ihre init Ändern einer Nachricht zu senden, dass die Daten an den Port sendet:

-- INIT 


init : (Model, Cmd Msg) 
init = 
    -- (Model 0, f()) 
    (Model 0, send Ask) 


send : msg -> Cmd msg 
send msg = 
    Task.perform identity identity (Task.succeed msg) 
+0

Ich weiß nicht genug Elm zu "Design-Entscheidungen" ... –

+0

Ooh das ist Elm 0.17 so könnte es Syntax ändern –

+0

Ich überprüfte ... 'f' wird definitiv aufgerufen. Ich habe versucht, eine 'console.log' –

2

Wenn Sie nur suchen Standardwerte von Javascript zu Ihrem Elm App zu schicken, Sie programWithFlags verwenden können, zu beseitigen die Notwendigkeit, Draht in einen Hafen, um zu versuchen, die noch nicht eingerichtet ist:

main = 
    Html.programWithFlags 
    { init = init 
    , view = view 
    , update = update 
    , subscriptions = subscriptions 
    } 

-- INIT 
type alias Flags = { initialValue : Int } 

init : Flags -> (Model, Cmd Msg) 
init flags = (Model flags.initialValue, Cmd.none) 

Dies ermöglicht es Ihnen, dass der Anfangswert durch Javascript wie folgt zu senden: