【发布时间】:2017-08-21 05:01:09
【问题描述】:
我正在尝试在 Fsharp 中编写一个 riot 标签,但如果不更改 riot,我无法这样做。
在 JavaScript 中我应该 provide a function like:
function(opts) {
this.on("update",function(opts){
this.opts = opts || this.opts;
});
}
然后riot 将call this function 使用Function.prototype.call:
if (impl.fn) { impl.fn.call(this, opts); }
在 F# 中,我尝试了以下操作:
[<Emit("this")>]
let isThis (x: 'a) : obj = jsNative
let bind fn =
fun o ->
fn (isThis 1) o
[<Emit("$0 === undefined")>]
let isUndefined (x: 'a) : bool = jsNative
bind
(
fun me opts ->
me?on(
"update"
,(
fun opts ->
if not (isUndefined opts) then
me?opts <- opts
()
)
)
)
但是;绑定函数被转译为:
export function bind(fn, o) {
return fn(this)(o);
}
当我想咖喱时不咖喱,我正在寻找的输出是:
export function bind(fn) {
return function(o){
return fn(this)(o);
}
}
我可以让它工作的唯一方法是将 riot.js 更改为:
if (impl.fn) { impl.fn(this)(opts); }
并通过以下方式在 F# 中提供我的功能:
fun me opts ->
me?on(
"update"
,(
fun opts ->
if not (isUndefined opts) then
me?opts <- opts
()
)
)
更改第 3 方库以满足转译器生成的代码并不理想。转译器有没有办法生成我正在寻找的输出?
[更新]
不需要更改第 3 方代码的更好方法是提供绑定函数作为第 3 方 JavaScript:
然后导入它并在你的模板代码文件中使用绑定:
let JSI =
bind<(obj -> obj -> unit) -> obj>
"../../../js/3rd/JSI.js"
bind
(
fun me opts ->
me?on(
"update"
,(
fun opts ->
if not (isUndefined opts) then
me?opts <- opts
()
)
)
)
【问题讨论】: