Websharper.UI.Next中不会发生Doc.Checkbox'change'事件

时间:2015-06-13 12:35:50

标签: web f# websharper

我的反应性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

最可悲的是带复选框的元素甚至没有我的事件处理程序。在浏览器中调试时很明显。

1 个答案:

答案 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”。