F# 无法通过'Var<;将文档片段嵌入WebShapper页面;Doc>`

F# 无法通过'Var<;将文档片段嵌入WebShapper页面;Doc>`,f#,websharper,F#,Websharper,我对使用WebSharper还很陌生,我可能做得不对。 我的目标是通过更新表示要更新页面的一部分的Var变量,从而能够根据用户操作更新页面的内容。我很高兴知道是否可以从服务器端代码更新Var,并将其反映在用户的浏览器中 下面是一个简单的例子: let TestPage ctx = let clientPart = Var.Create <| Doc.Empty clientPart .Value <- div [] [ text "This content is dy

我对使用WebSharper还很陌生,我可能做得不对。 我的目标是通过更新表示要更新页面的一部分的
Var
变量,从而能够根据用户操作更新页面的内容。我很高兴知道是否可以从服务器端代码更新
Var
,并将其反映在用户的浏览器中

下面是一个简单的例子:

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 @> ]
    ]

下面是一个在服务器端调用RPC并将其存储到客户机
Var
中的示例:

模块服务器功能=
让可变服务器状态=(“零”,0)
让[]addToState n=async{
let state,counter=ServerState
设newCounter=counter+n
让newState=如果newCounter=0,则为“零”,否则为“非零”
服务器状态]
模块ClientFunctions=
开放式Web服务器
打开WebSharper.UI
打开webharper.UI.Html
开放式服务器功能
让zeroState=Var.创建“不知道”
将clientDoc()设为
分区[][
h1[]文本“服务器上的零状态:”]
h2[][text zeroState.V]
Doc.Button“increment”[](fun()->async{let!state=addToState 1
零状态,设置状态
}|>Async.Start)
文档按钮“减量”[](fun()->async{let!state=addToState-1
零状态,设置状态
}|>Async.Start)
]
模块服务器=
openglobal.Owin
打开Microsoft.Owin.Hosting
打开Microsoft.Owin.StaticFiles
打开Microsoft.Owin.FileSystems
打开WebSharper.Owin
打开webharper.UI.Server
打开webharper.UI.Html
EndPointServer类型=
|[]您好
|关于
让url=”http://localhost:9006/"
让rootdir=@.\website
let site()=webharper.Application.MultiPage(有趣的上下文(s:EndPointServer)->
printfn“服务页面:%A”s
内容页(
标题=(sprintf“测试%A”s)

,Body=[h1[][文本我认为服务器端的
Var
不会触发客户端的更改。您的
Var
s和
视图都需要在客户端进行维护和更新。如果您想从服务器向客户端发送消息,您需要在服务器和客户端之间创建不同的通信通道就像WebSockets的例子一样。@AMieres,这很有意义。你知道如何同步客户端变量和服务器端变量的状态吗?我的目标是在服务器端生成部分页面(在初始加载时)然后主要在客户端处理用户输入/操作。我相信我可以通过修改一些专用变量来实现这一点,但它们需要在客户端和服务器上都可以访问。要实现这一点,我需要做什么特殊的事情吗?客户端始终可以使用属性
[]在服务器上调用函数
查询服务器上的任何值(不应在
Var
中,因为它们在服务器中没有意义)然后将结果存储到
Var
中,从中可以构造
Doc
。只要事件起源于客户端,该文档就可以工作。是否您的案例或值在客户端不知道的情况下在服务器中更改?@AMieres,我相信这确实说明了情况。客户端当前执行一个RPC来修改服务r状态。我需要修改后的状态才能以某种方式返回到客户端,因此我想我必须深入挖掘客户端的rpc消费。正如我所说的,我对WebSharper是新手,我试图让事情尽可能简单。但是,我对var迷路了——服务器端var与客户端无关这一点并不明显ide one。谢谢你到目前为止的建议。如果你把这个作为答案的话,我很乐意给你一些分数。
type SomeTemplate = Template<"SomeTemplate.html">
clientDoc.Value <- SomeTemplate().Doc()
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
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() @> ]) 
                  )