2

我有一个使用 websockets 在 SAFE-Stack 中构建的应用程序,或多或少遵循这里的方法:https ://github.com/CompositionalIT/safe-sockets

它工作正常,但 Elmish 调试器不喜欢此示例中的 WsSender 类型:


type ConnectionState =
        | DisconnectedFromServer
        | ConnectedToServer of WsSender
        | Connecting

        member this.IsConnected =
            match this with
            | ConnectedToServer _ -> true
            | DisconnectedFromServer | Connecting -> false

    and WsSender = Msg -> Unit

在浏览器控制台中给出以下错误消息:

ElmishDebuggerMessage

谁能告诉我如何解决这个问题?(假设它是可修复的并且我已正确诊断出问题。)谢谢。

4

2 回答 2

2

您看到此错误是因为 Elmish.Debugger 使用 Thoth.Json 将您的 Msg/Model 序列化为 JSON 格式。

该类型WsSender不能以 JSON 格式表示,因为它是一个函数。所以 Thoth.Json 要求你解释它应该如何编码这种类型。

您可以通过创建所谓的extraCoder类似来做到这一点:

在您的情况下,您将不得不“只是”创建一个虚假的编码器/解码器以使调试器满意。

module CustomEncoders =

    let wsSenderEncoder (_ : WsSender) = Encode.string "WsSender function"

    let wsSenderDecoder = Decode.fail "Decoding is not supported for WsSender type"

    let myExtraCoders =
        Extra.empty
        |> Extra.withCustom wsSenderEncoder wsSenderDecoder 


    let modelEncoder = Encode.Auto.generateEncoder(extra = myExtraCoders)
    let modelDecoder = Decode.Auto.generateDecoder(extra = myExtraCoders)

在您的程序创建中,您应该替换Program.withDebuggerProgram.withDebuggerCoders为其提供您创建的编码器和解码器。

Program.withDebuggerCoders CustomEncoders.modelEncoder CustomEncoders.modelDecoder
于 2020-04-20T18:16:02.937 回答
0

我尝试了一些尝试并想出一些东西,如果需要的话,可以更容易地拥有多个额外的编码器。这似乎有效 - 认为它可能对其他人有帮助。


module CustomEncoders =

    let inline addDummyCoder<'b> extrasIn =
        let typeName = string typeof<'b>
        let simpleEncoder(_ : 'b) = Encode.string (sprintf "%s function" typeName)
        let simpleDecoder = Decode.fail (sprintf "Decoding is not supported for %s type" typeName)
        extrasIn |> Extra.withCustom simpleEncoder simpleDecoder

    let inline buildExtras<'a> extraCoders =
        let myEncoder:Encoder<'a> = Encode.Auto.generateEncoder(extra = extraCoders)
        let myDecoder:Decoder<'a> = Decode.Auto.generateDecoder(extra = extraCoders)
        (myEncoder, myDecoder)

type TestType = Msg -> Unit
type TestType2 = string -> Unit

let extras = Extra.empty
                |> CustomEncoders.addDummyCoder<TestType>
                |> CustomEncoders.addDummyCoder<TestType2>
                |> CustomEncoders.buildExtras<Model.Model>


#if DEBUG
open Elmish.Debug
open Elmish.HMR
#endif


Program.mkProgram Model.init Model.update View.render
|> Program.withSubscription subs 
#if DEBUG
|> Program.withConsoleTrace
#endif
|> Program.withReactBatched "elmish-app"
#if DEBUG
|> Program.withDebuggerCoders (fst extras) (snd extras)
#endif
|> Program.run


如果有人对如何做到这一点有更好的了解,我很乐意用他们的建议更新这个答案。此外,泛型类型中的撇号似乎扰乱了上面的代码美化器——我需要做些什么来解决这个问题吗?

于 2020-04-20T19:12:21.597 回答