dotnet-websharper / ui

A reactive UI library for WebSharper.
https://websharper-samples.github.io/ui/
Apache License 2.0
77 stars 22 forks source link

Binding `ListModel`s in `Doc`s #270

Open granicz opened 1 year ago

granicz commented 1 year ago

Given shoppingCart, a ListModel<string, (Product * int)> value, meant to model an imaginary shopping cart with products identified by a string key, one ususally tries the following variants to bind it to reactive DOM:

// 1. Works
shoppingCart.View.Doc(fun cart ->
    cart
    |> Seq.map (fun (product, quantity) ->
        div [] [
            text $"""{product.Title} x {string quantity}"""
        ]
    )
    |> Doc.Concat
)
// 2. Works
shoppingCart.View.DocSeqCached(fun (product, quantity) ->
    div [] [
        text $"""{product.Title} x {string quantity}"""
    ]
)
// 3. Doesn't work
shoppingCart.Doc(fun (product, quantity) ->
    div [] [
        text $"""{product.Title} x {string quantity}"""
    ]
)
// 4. Doesn't work
Doc.BindListModel(fun (product, quantity) ->
    div [] [
        text $"""{product.Title} x {string quantity}"""
    ]
) shoppingCart
// 5. Works
Doc.BindSeqCached(fun (product, quantity) ->
    div [] [
        text $"""{product.Title} x {string quantity}"""
    ]
) shoppingCart.View

No 3 and No 4 are variants that don't reactively update on changing the items in the shopping cart. This is either a bug or these variants are confusing and misleading: there is little point in mapping a ListModel to reactive DOM if we only use the current snapshot of its values.