I found a way to achieve what I want:

In the view function that adds the Ace editor, I send a message once it is 
ready (I assume in this use case it is fine to use Json.succeed, no?):

type Msg = EditorReady

renderScript : Script -> Html Msg
renderScript script =
    node "juicy-ace-editor"
        [ id "editor-container", on "editor-ready" (Json.succeed EditorReady
) ]
        [ ... ]

In my update function, I trigger the port once the message arrives:

port configureAce : String -> Cmd m

update : Msg -> AppState -> ( AppState, Cmd Msg )
update msg appState =
    case msg of
        SelectView i ->
            ( { appState | viewSelected = i }, Cmd.none )

        EditorReady -> 
            ( appState, configureAce "ace/theme/monokai")

best,
Robert


On Thursday, July 7, 2016 at 5:04:55 PM UTC+2, Robert Walter wrote:
>
> Hello,
>
> first of all: if someone knows of another, better way of achieving what 
> I'm trying to do, I'd be happy to hear about it.
>
> In my Elm app, I embed an Ace editor using juicy-ace 
> <https://github.com/Juicy/juicy-ace-editor>. In order to configure the 
> editor instance (e.g. setting a certain theme) I think I need to use a port 
> to call some JavaScript.
> However, my editor is not always in the dom. In other words, it is 
> conditionally rendered based on the selected tab of my app. Here's a 
> screenshot to illustrate that.
>
>
> <https://lh3.googleusercontent.com/-nf7rjMeBqfI/V35iG0-lcfI/AAAAAAAAA0A/q7Q4eAgbpMkGMjDCOZdgkTZEKgysP7kmQCLcB/s1600/aceIssue1.png>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> My current "solution" doesn't quite work, because I "trigger" the port 
> when the user clicks on the "Dialog" tab. This action updates my model to 
> render the dialog tab next,
> but the port is triggered before the view is rendered, so that I cannot 
> apply any theme or other configuration.
> When I click the dialog tab a second time, the configuration is applied 
> just fine (hence, I know the JavaScript side works),
>
> Here are some code snippets that show the relevant parts.
>
> index.html -- where I want to configre the Ace Editor.
>   <script type="text/javascript">
>     var app = Elm.App.fullscreen();
>
>     // configureAce is the port in Elm
>     app.ports.configureAce.subscribe(function(theme) {
>       var aceContainer = document.getElementById("editor-container");
>
>       console.log("Called!");
>
>       if(aceContainer != null)
>         aceContainer.editor.setTheme(theme);
>     });
>   </script>
>
> App.elm -- my main *.elm file, where I "trigger" the port 
> port configureAce : String -> Cmd a
>
> update : Msg -> AppState -> ( AppState, Cmd Msg )
> update msg appState =
>     case msg of
>         SelectView i ->
>             let
>               cmd = 
>                 if ((indexToView i) == Dialog)
>                 then configureAce "ace/theme/monokai"
>                 else Cmd.none 
>             in
>             ( { appState | viewSelected = i }, cmd)
>         ...
>
> One thing I tried but failed with the same behavior as above was the 
> following: Instead of directly triggering the port when the Dialog tab is 
> selected, I wanted to create a Cmd that will be run by elm and only once it 
> is fed back in the update function, I trigger the port, like so:
>
> port configureAce : String -> Cmd a
>
> update : Msg -> AppState -> ( AppState, Cmd Msg )
> update msg appState =
>     case msg of
>         SelectView i ->
>             let
>               cmd = 
>                 if ((indexToView i) == Dialog)
>                 then (toCmd ConfigureAce) --configureAce 
> "ace/theme/monokai"
>                 else Cmd.none 
>             in
>             ( { appState | viewSelected = i }, cmd )
>         
>         ConfigureAce -> 
>           (appState, configureAce "ace/theme/monokai")
>
>
> toCmd : msg -> Cmd msg
> toCmd msg =
>   Task.perform (always msg) (always msg) (Task.succeed msg)
>
> Thanks
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to