How difficult would it be to implement a View.Computed function similar to knockout's computed observable. So instead of writing

1
2
3
4
let pageStr = 
    View.Map2 (fun b pg -> 
                "Page "+(if b then ".." else pg.ToString())) 
                m.Fetching.View m.Page.View

one could write something like:

1
2
3
let pageStr' = 
    View.Computed (fun () -> 
        "Page "+(if m.Fetching.Value then ".." else m.Page.Value.ToString())) 

View.Computed dynamically creates the dataflow. This could eliminate a LOT of View.Maps, Snapshots, etc...

  • loic.denuziere

    There is an experimental branch I started some time ago that would allow an even shorter syntax, not even needing a fun () ->, thanks to WebSharper macros. I haven't touched it in a bit, but it looks something like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    // Usual UI.Next corresponding to your code
    let pageStr =
        View.Map2 (fun f p ->
                	"Page " + if f then ".." else p.ToString())
                    m.Fetching m.Page
    
    // V version
    let pageStr =
        V ("Page " + if m.Fetching.V then ".." else m.Page.V.ToString())

    It even makes HTML functions like div and text macros so that you don't need to wrap in a V() when building markup:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // Usual UI.Next
    let someTextNode : Doc =
        View.Map2 (fun f p ->
            		"Page " + if f then ".." else p.ToString())
                    m.Fetching m.Page
        |> textView
    
    // V version
    let someTextNode : Doc =
        text ("Page " + if m.Fetching.V then ".." else m.Page.V.ToString())

    It doesn't actually dynamically create the dataflow, instead it transforms the code at compile time and generates the same set of Maps, Map2s, etc that you would otherwise write yourself. I hope to have time to go back to it as soon as possible :)