简体   繁体   中英

How can I add a HTML control dynamically to the result view in Fable F#?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM