Невозможно вставить фрагмент документа в страницу WebSharper через `Var <Doc>` - PullRequest
0 голосов
/ 02 января 2019

Я довольно новичок в использовании WebSharper и могу делать что-то неправильно. Моя цель - иметь возможность обновлять содержимое моей страницы в результате действий пользователя, обновляя переменную Var<Doc>, представляющую часть страницы, подлежащую обновлению. Я был бы рад узнать, могу ли я обновить Var<Doc> из серверного кода и отобразить его в браузере пользователя.

Ниже приведен краткий пример:

let TestPage ctx =
    let clientPart = Var.Create <| Doc.Empty
    clientPart .Value <- div [] [ text "This content is dynamically inserted" ]

    Templating.Main ctx EndPoint.Home "Home" [
        h1 [] [text "Below is a dynamically inserted content:"]
        div [] [ client <@ clientPart .View |> Doc.EmbedView @> ]
    ]

Я получаю ошибку:

System.Exception: Ошибка во время преобразования RPC JSON ---> System.Exception: Не удалось найти переведенное имя поля для записи 'в типе WebSharper.UI.Elt с полями: docNode, elt, rvUpdates, updates

Документация WebSharper 4 относительно Views также гласит:

Он будет запущен только тогда, когда результирующее представление включено в документ, используя один из этих методов :

  • Doc.BindView
  • Doc.EmbedView
  • TextView

и т. Д.

Появляется похожая ошибка, если я попробую это вместо:

type SomeTemplate = Template<"SomeTemplate.html">
clientDoc.Value <- SomeTemplate().Doc()

В приведенном выше коде Templating.Main такое же, как в проекте WebSharper по умолчанию:

module Templating =
    ...
    let Main ctx action (title: string) (body: Doc list) =
        let t = MainTemplate().Title(title).MenuBar(MenuBar ctx action).With("Body", body)
        let doc : Doc = t.Doc()
        doc |> Content.Page

1 Ответ

0 голосов
/ 03 января 2019

Вот пример вызова RPC на стороне сервера и сохранения его в клиенте Var<>:

module ServerFunctions =

    let mutable ServerState = ("Zero", 0)

    let [< Rpc >] addToState n = async {
        let state, counter = ServerState
        let newCounter = counter + n
        let newState   = if newCounter = 0 then "Zero" else "NonZero"
        ServerState <- newState, newCounter
        return newState
    }

[< JavaScript >]
module ClientFunctions =
    open WebSharper
    open WebSharper.UI
    open WebSharper.UI.Html
    open ServerFunctions

    let zeroState = Var.Create "do not know"

    let clientDoc() = 
        div [] [
            h1 [] [ text "State of zero on server:" ]
            h2 [] [ text zeroState.V ]
            Doc.Button "increment" [] (fun () -> async { let! state = addToState  1
                                                         zeroState.Set state 
                                                        } |> Async.Start)
            Doc.Button "decrement" [] (fun () -> async { let! state = addToState -1
                                                         zeroState.Set state 
                                                        } |> Async.Start)
        ]

module Server =
    open global.Owin
    open Microsoft.Owin.Hosting
    open Microsoft.Owin.StaticFiles
    open Microsoft.Owin.FileSystems
    open WebSharper.Owin
    open WebSharper.UI.Server
    open WebSharper.UI.Html

    type EndPointServer = 
        | [< EndPoint "/" >] Hello
        | About

    let url = "http://localhost:9006/"
    let rootdir = @"..\website"
    let site()  = WebSharper.Application.MultiPage(fun context (s:EndPointServer) -> 
                    printfn "Serving page: %A" s
                    Content.Page(
                        Title= ( sprintf "Test %A" s)
                      , Body = [ h1 [] [ text <| sprintf "%A" s ] 
                                 Html.client <@  ClientFunctions.clientDoc() @> ]) 
                  )                      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...