I am trying to understand the very first project that is generated when you create a elmish/fable project like so: dotnet new fable-react-elmish
:
let view (model: Model) dispatch =
let resultView =
match model.downloaded with
| Ok r ->
h3 [ Style [CSSProp.Color "blue"] ] [ str r ]
| Error er ->
h3 [ Style [CSSProp.Color "red"] ] [ str er ]
div [] [
h1 [] [ str "React Elmish demo" ]
button [ OnClick (fun _ -> dispatch OnDownloadClicked) ] [ str "Download" ]
button [ OnClick (fun _ -> dispatch ResetClicked) ] [ str "Reset" ]
div [] [ h2 [] [ str "Download result:" ]; resultView ]
]
I understand that every time one of the functions OnDownloadClicked
or ResetClick
is called, a <h3>
HTML control is displayed as the last control of the HTML page, overwriting the old one. (Probably the whole page is reloaded, but I'm not sure)
But how would I modify the above example in order to have a new <h3>
element added to the view every time the OnDownloadClicked
function gets called? In other words: I'd like to have all formerly displayed <h3>
elements being kept on the view. Any hints (also those pointing to examples) are welcome.
Judging by the code, the type Model
must be a record that looks something like:
type Model = {
...
downloaded: Result<string, string>
...
}
This downloaded
field must be updated in the update
function as a result of OnDownloadClicked
message.
👆 those are assumptions I'm making based on what you showed here (the view
function), but I don't know for sure, because you're not showing those parts of the code.
Anyway, assuming the assumptions are correct, you can just keep a history of Result<string, string>
values instead of just the last one. To do this, modify the Model
type to hold a list of them:
type Model = {
...
downloadHistory: list<Result<string, string>>
...
}
Then have your update
function append most recent value to the list instead of replacing the field with it.
Then in your view
function you can produce a list of h3
tags by mapping the resultView
function over the downloadHistory
list:
let resultView r =
match r with
...
...
div [] (h2 [] [ str "Download result:" ] :: List.map resultView model.downloadHistory)