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.