0

我有反应式 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

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

4

1 回答 1

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更复杂但通常更可取的解决方案是通过 a监听更改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”。

于 2015-06-15T13:53:50.810 回答