首页 文章

从F#Fable调用ES第三方脚本方法

提问于
浏览
3

我正在尝试让Fable正确编译以下代码,但我无法这样做:

module AppView
#r "../../../node_modules/fable-core/Fable.Core.dll"
open Fable.Core
open Fable.Import.Browser
open Fable.Core.JsInterop
[<Import("default", from="../../../js/3rd/riot.js")>]
module riot_js =
  let mount:((string*obj)->array<obj>) = jsNative

type App
  (
    tagName:string
    ,state
    ,store
  ) = 
  member public x.AppTag =
    (riot_js?mount ("app", state))
    // does not compile: The value or constructor 'riot_js' is not defined.
    // (riot_js.mount ("app", state))
    // compiles wrongly to: riot_js.mount(["app", this.state]);

尝试 riot_js?mount 会神奇地导致riot_js不再存在并尝试 riot_js.mount 编译成 riot_js.mount(["app", this.state]); .

Mount不会采用一个参数而是2个,但它要么不会发生错误,要么发生错误 .

现在我有一个最奇怪的解决方案:

[<Emit("riot_js")>]
let riot_js (x: int): obj = jsNative
...
((riot_js 1)?mount ("app", state))

这会返回一个数组但是Fable不会让我以“正常”方式获取第一个元素:

((riot_js 1)?mount ("app", state))?[0]

[ 给我红色,错误 Unexpected symbol '[' in expression. Expected identifier, '(' or other token.

((riot_js 1)?mount ("app", state)).[0]

一切都带红色,错误 The field, constructor or member 'Item' is not defined.

以下“作品”

((riot_js 1)?mount ("app", state))?``0``

并编译为:

riot_js.mount("app", this.state)["0"];

不是有人能得到的最好结果 . 我会让这个问题暂时搁置一段时间,然后在与Fable打开2个问题之前为它设置一个星期左右的赏金 .

1 回答

  • 0

    以下似乎编译到正确的ES并且不需要 ? 因此它将被强类型化 .

    open Fable.Core.JsInterop
    type Riotjs = 
      {
        mount:(System.Func<string,obj,string []>)
      }
    let riot = (importAll<obj> "../js/3rd/riot.js") :?> Riotjs
    let app = riot.mount.Invoke("app",(createObj []))
    

    我将初始状态设置为键入 obj ,但也可以使用强类型应用程序状态 .

    生成的ES是:

    export var app = riot.mount("app", {});
    

相关问题