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