fn update(msg : Msg, model : Model) -> (Cmd[Msg], Model) {
match msg {
Msg::Click(id) => {
// create a command to tell rabbit-tea scroll to the element with the given id
let cmd = @nav.scroll_to(id)
let updated_model = {...}
(cmd, updated_model)
}
}
}type Cmd[M] (Events[M]) -> Unitfn delay[M](msg : M, ms : Int) -> Cmd[M] {
Cmd(fn(events){
set_timeout(fn(){ events.trigger_update(msg) }, ms)
})
}
extern "js" fn set_timeout(f : () -> Unit, ms : Int) = "(f,ms) => setTimeout(f, ms)" +---> update(msg1, old_model) ---> new_model1
|
old_model--+
|
+---> update(msg2, old_model) ---> new_model2Now you have two models, new_model1 and new_model2. Which model should
be used in the view?In some other UI frameworks, this issue could occur. In rabbit-tea, it can
be avoided by using the Cmd pattern. If you doesn't use asynchronous
functions in update, e.g. @cmd.attempt and @cmd.perform, you will never
met this problem.fn delay[M](msg : M, ms : Int) -> Cmd[M] {
Cmd(events => {
set_timeout(() => { events.trigger_update(msg) }, ms)
})
}
extern "js" fn set_timeout(f : () -> Unit, ms : Int) = "(f,ms) => setTimeout(f, ms)"type Events[M]fn[M] Events::new(on_url_changed : (Url) -> Unit, on_url_request : (UrlRequest) -> Unit, on_update : (M) -> Unit) -> Events[M]TEA web UI framework for MoonBit
Dependencies