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

时间:2017-08-19 07:07:28

标签: f# fable-f#

我正在尝试让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 :(得分: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", {});