Das folgende Beispiel, das etwas ähnlich wie Sie beschreibt.
modal
mit einer Adresse präsentiert wird, um die aktuellen Fensterabmessungen und ELM-html Html
Komponente (was die Sache, wie ein Datumsauswahl oder eine Form zu fokussiert) (a ‚entlassen‘ Ereignis zu senden).
Wir fügen einen Click-Handler an das umgebende Element an; Nachdem wir ihm eine passende ID gegeben haben, können wir herausfinden, ob empfangene Klicks auf ihn oder das Kind zutreffen, und diese entsprechend weiterleiten. Das einzige wirklich clevere Bit ist die Bereitstellung von customDecoder
, um Klicks auf das untergeordnete Element herauszufiltern.
Anderswo ändert sich unser Modellzustand bei Empfang des 'entlassen' -Ereignisses so, dass wir nicht mehr modal
anrufen müssen.
Dies ist eine recht große Codebeispiel, das die Verwendung eines fairen paar Ulme Pakete macht so fragen Sie bitte, ob alles weitere Erklärung erfordert
import Styles exposing (..)
import Html exposing (Attribute, Html, button, div, text)
import Html.Attributes as Attr exposing (style)
import Html.Events exposing (on, onWithOptions, Options)
import Json.Decode as J exposing (Decoder, (:=))
import Result
import Signal exposing (Message)
modal : (Signal.Address()) -> (Int, Int) -> Html -> Html
modal addr size content =
let modalId = "modal"
cancel = targetWithId (\_ -> Signal.message addr()) "click" modalId
flexCss = [ ("display", "flex")
, ("align-items", "center")
, ("justify-content", "center")
, ("text-align", "center")
]
in div (
cancel :: (Attr.id modalId) :: [style (flexCss ++ absolute ++ dimensions size)]
) [content]
targetId : Decoder String
targetId = ("target" := ("id" := J.string))
isTargetId : String -> Decoder Bool
isTargetId id = J.customDecoder targetId (\eyed -> if eyed == id then Result.Ok True else Result.Err "nope!")
targetWithId : (Bool -> Message) -> String -> String -> Attribute
targetWithId msg event id = onWithOptions event stopEverything (isTargetId id) msg
stopEverything = (Options True True)
Können Sie nicht etwas Ähnliches wie die Sachen Reagieren versuchen Sie gefunden? Ein globaler Click-Handler sendet eine "Action", die in der 'update' -Funktion des Parents der Komponente (oder der Komponente selbst, wenn Sie es als Teil ihrer Aufgabe betrachten, wann sie ausgeblendet werden soll) behandelt wird und bewertet, ob etwas benötigt wird versteckt werden, dann reflektiere das in deinem 'Model'. – Apanatshka
Danke für den Vorschlag, ich werde versuchen, so etwas zu tun, und wenn es funktioniert, werde ich die meisten meine Lösung (ich muss nur mehr über Native js Module zuerst lernen). Mein Hauptanliegen, diesen Weg einzuschlagen (vorausgesetzt, Sie meinen, die Handler an Mount-/Unmount-Events wie bei den React-Lösungen anzuhängen), war, dass dies den Zweck von FRP zunichte machen könnte, wenn wir die auferlegten Beschränkungen sowieso brechen.Aber ich erkannte, dass es in Ordnung sein könnte, wenn es nur in seltenen Fällen wie diesem verwendet wird. – ave
Ich kenne keine richtige In-Elm-Lösung, daher schlage ich vor, dass Sie die React-Lösung replizieren, um Ihr Problem jetzt zu beheben. Aber öffne eine Diskussion auf der Mailingliste zu diesem Thema. Es sollte eine richtige Lösung geben, die diese Art von Hacks nicht erfordert;) – Apanatshka