使用 WebSharper 在服务器端呈现 SVG
Using WebSharper to render SVGs server-side
我正在尝试在服务器端生成 SVG,然后使用 WebSharper 的 RPC 机制将它们传递给客户端。我基于 websharper-web
模板,使用 dotnet 核心。
为了完整起见,我这样渲染模板:
// Site.fs
let Draw ctx =
Templating.Main ctx EndPoint.Home "Home" [
h1 [] [text "Say Hi to the server!"]
div [] [client <@ Artery.Main() @>]
]
我定义了一个 RPC 方法,return我的 SVG:
module Server =
[<Rpc>]
let FetchDrawing () =
let center = {Svg.Point.X=50; Svg.Point.Y=50}
let r = 25
let circle = Svg.Shape.Circle(center=center, radius=r)
async {
return circle |> Svg.render
}
// Returns an SvgElement.circle with cx, cy, and r set
到目前为止一切正常,但我无法弄清楚如何在客户端中正确加载它。我得到的最接近的是:
[<JavaScript>]
module Artery =
let Main() =
let circle = Server.FetchDrawing()
div [] [
SvgElements.svg [SvgAttributes.height "100"
SvgAttributes.width "100"] [
Doc.Async circle
]
]
这个:
- 类型检查和编译
- 运行
- 运行时抛出 JavaScript 错误
具体来说,我得到 TypeError: x is not a function
。 SourceMaps link 错误深入到一个名为 Snap.fs
的 WebSharper 库中,它揭示了......相对较少的光。
这是 WebSharper 中的错误吗? 这应该有效吗?在这样的客户端文档中包含 Async<Doc>
的正确方法是什么?如果可能的话,我 更喜欢 不要使用 jQuery ——我宁愿 return JS 在 SVG 中异步加载,而不是 jQuery 稍后插入 - 但如果这是这里的最佳做法,我愿意接受 JQuery 的回答。
快速回答是否定的,不幸的是,这不会按原样工作,并且很抱歉当我早些时候在 F# Slack 频道上给你指导时没有想得更清楚。一方面,它是 WebSharper 编译器 限制 不发出不能将 Doc
值从 RPC 传递到客户端的警告。 WebSharper documentation page for remoting 列出了可以参与此类交换的类型的要求,不幸的是 Doc
不符合条件。
另一方面,有人提议使 RPC 调用更符合序列化,例如 dotnet-websharper/core#930,为使更多类型在 RPC 中工作铺平道路,或者可以直接支持Doc
RPC 中的值直接启用您的场景,仅仅是因为它们 应该 工作。这确实是少数需要涵盖的极端案例之一。
您现在可以做的是将您的 RPC 更改为 return 适合您需要的自定义 SVG 表示(例如一些形状的 AST),并使用它来转换为 Doc
在客户端。
我正在尝试在服务器端生成 SVG,然后使用 WebSharper 的 RPC 机制将它们传递给客户端。我基于 websharper-web
模板,使用 dotnet 核心。
为了完整起见,我这样渲染模板:
// Site.fs
let Draw ctx =
Templating.Main ctx EndPoint.Home "Home" [
h1 [] [text "Say Hi to the server!"]
div [] [client <@ Artery.Main() @>]
]
我定义了一个 RPC 方法,return我的 SVG:
module Server =
[<Rpc>]
let FetchDrawing () =
let center = {Svg.Point.X=50; Svg.Point.Y=50}
let r = 25
let circle = Svg.Shape.Circle(center=center, radius=r)
async {
return circle |> Svg.render
}
// Returns an SvgElement.circle with cx, cy, and r set
到目前为止一切正常,但我无法弄清楚如何在客户端中正确加载它。我得到的最接近的是:
[<JavaScript>]
module Artery =
let Main() =
let circle = Server.FetchDrawing()
div [] [
SvgElements.svg [SvgAttributes.height "100"
SvgAttributes.width "100"] [
Doc.Async circle
]
]
这个:
- 类型检查和编译
- 运行
- 运行时抛出 JavaScript 错误
具体来说,我得到 TypeError: x is not a function
。 SourceMaps link 错误深入到一个名为 Snap.fs
的 WebSharper 库中,它揭示了......相对较少的光。
这是 WebSharper 中的错误吗? 这应该有效吗?在这样的客户端文档中包含 Async<Doc>
的正确方法是什么?如果可能的话,我 更喜欢 不要使用 jQuery ——我宁愿 return JS 在 SVG 中异步加载,而不是 jQuery 稍后插入 - 但如果这是这里的最佳做法,我愿意接受 JQuery 的回答。
快速回答是否定的,不幸的是,这不会按原样工作,并且很抱歉当我早些时候在 F# Slack 频道上给你指导时没有想得更清楚。一方面,它是 WebSharper 编译器 限制 不发出不能将 Doc
值从 RPC 传递到客户端的警告。 WebSharper documentation page for remoting 列出了可以参与此类交换的类型的要求,不幸的是 Doc
不符合条件。
另一方面,有人提议使 RPC 调用更符合序列化,例如 dotnet-websharper/core#930,为使更多类型在 RPC 中工作铺平道路,或者可以直接支持Doc
RPC 中的值直接启用您的场景,仅仅是因为它们 应该 工作。这确实是少数需要涵盖的极端案例之一。
您现在可以做的是将您的 RPC 更改为 return 适合您需要的自定义 SVG 表示(例如一些形状的 AST),并使用它来转换为 Doc
在客户端。