Open Quelklef opened 2 years ago
You know, I think we could have a monad whose only effectual capabilities are reading and writing properties of a javascript object.
Probably would be a pain to implement, but it'd work.
It definitely does feel kinda weird to me to have an effect that happens "after render" -- sounds like race conditions waiting to happen. Perhaps worse, it seems to make the view impure: although it would remain a pure function, there's nothing stopping me from making an afterUpdate
prop which, say, relies on the current time. Yuck!
Really what I'd like is for afterUpdate
to take a Node -> Node
, but the DOM API doesn't really support that kinda pure thinking...
I think a fair middle ground might be to allow getting+setting in the monad, but no method calls.
I don't think this would perfectly section "safe" from "unsafe" -- there are safe Effect
s, and there are unsafe gets/sets. But it would probably be pretty close.
Oh, I was not clear enough. My imagined monad would only allow reading and writing to the properties of a single object, which we would make the node. So you could not make something that relies on current time.
No, I got that. I was just affirming that I think allowing an Effect
update to run "after render" seems dangerous
Useful for attribute-like things that currently aren't Attributes, such as setting the value of an without moving the caret
As we have discussed, this can be achieved with an event listener, since they are effectual. Could you provide another example to motivate this? Also keep in mind afterRender already exists, which can implement this behaviour. It is at the cost of having to identify the node globally, but you do also gain more control over when you want to use it, since it's used in an effectual context (update
).
keep in mind afterRender already exists, which can implement this behaviour
Kind of. If view
were Model -> Writer Msg (Html Msg)
, then we could have an AfterRender (Effect Unit)
variant in our message and tell customAttributeEffect
within our view. But since view
is Model -> Html Msg
, we cannot do this. In other words, an Html Msg
has no way to perform an effect "immediately", only after some event (click, etc).
(Alternatively, a performImmediately :: forall msg. (Node -> msg) -> Attribute msg
would also work.)
Could you provide another example to motivate this?
I think so. In my Y client, there were some calculations I wanted to do based on the placement of a node on screen. This means I wanted to render the node, check some computed properties, and touch up its positioning or whatever.
To be fair, afterUpdate
is probably not the only solution to this. But I'm not sure there's any good solution with the current Elmish infrastructure.
Maybe add:
This would allow making any modification to an element to be expressed as an
Attribute
.Pros:
Attribute
s, such as setting the value of an<input>
without moving the caretProperty
sCons:
Effect
, or, worse, modifying the given node's parentNode.