我的反应性Var变量varDone和Doc.Checkbox的表示名为cbDoc。更改varDone的值后,我需要调用我的函数。为此,我编写了以下伪代码中说明的代码:
open WebSharper
open WebSharper.UI.Next
open WebSharper.UI.Next.Html
open WebSharper.UI.Next.Notation
// declaring reactive bool variable
let varDone = Var.Create false
(* something else *)
// creting Doc-representation of my model
let renderModel model =
// declaring its representation Doc element
let cbDone = Div0 [ Doc.CheckBox [ "type" ==> "checkbox" ] varDone ]
let result'doc = // a Doc-representation, that contains cbDone
let my'handler() : unit -> unit = // a function that should be called when changing the value of varDone
// add an event handler for the element cbDone changes
(Doc.AsPagelet cbDone).Body.AddEventListener( "change", my'handler, false )
result'doc
但遗憾的是,当复选框更改时不会发生任何事件。问题是,我做错了什么,还有另一种方法来回应varDone变量值的变化吗?
UPD
最可悲的是带复选框的元素甚至没有我的事件处理程序。在浏览器中调试时很明显。
答案 0 :(得分:1)
编辑:这是使用当前WebSharper.UI实现下面的第二个解决方案:
let cbDone =
div [] [
Doc.CheckBox [
attr.``type`` "checkbox"
on.viewUpdate varDone.View (fun _ _ -> my'handler())
] varDone
]
Doc.AsPagelet
会在文档周围添加一个包装器,因此您要向该包装器添加一个事件侦听器。即使它没有,您也会向您创建的Div0
而不是CheckBox
本身添加事件监听器。
话虽如此,这里有两种解决方案:
简单的解决方案是在Attr.Handler
中使用CheckBox
:
let cbDone =
Div0 [
Doc.CheckBox [
"type" ==> "checkbox"
Attr.Handler "change" (fun _ -> my'handler())
] varDone
]
更复杂但通常更可取的解决方案是通过varDone
收听View
的更改,而不是听取元素上的事件。
现在,UI.Next工作的方式,实际上只计算连接到接收器的视图(即渲染文档),所以如果你只做这样的事情就不会发生任何事情:
let _ = varDone.View |> View.Map (fun _ -> my'handler())
相反,上述表达式(具有类型View<unit>
)的结果值需要连接到返回的文档。您可以使用以下帮助程序(我们可能很快会以某种形式添加到UI.Next中):
let AddViewListener (view: View<'T>) (f: 'T -> unit) (doc: Doc) =
view
|> View.Map (fun x -> f x; Doc.Empty)
|> Doc.EmbedView
|> Doc.Append doc
你可以这样使用:
let cbDone =
Div0 [ Doc.CheckBox [ "type" ==> "checkbox" ] varDone ]
|> AddViewListener varDone.View (fun _ -> my'handler())
上述代码基本上意味着“只要cbDone
在呈现的文档中,对varDone
的任何更改都将触发my'handler
”。