0

cbDoc という名前の表現用に、リアクティブな Var 変数 varDone と Doc.Checkbox があります。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 で以下の 2 番目のソリューションを実装する方法です。

let cbDone =
    div [] [
        Doc.CheckBox [
            attr.``type`` "checkbox"
            on.viewUpdate varDone.View (fun _ _ -> my'handler())
        ] varDone
    ]

何が起こるかというとDoc.AsPagelet、ドキュメントの周りにラッパーが追加されるため、そのラッパーにイベント リスナーを追加することになります。そうでない場合でも、Div0作成した 自体ではなく、作成した にイベント リスナーを追加することになりCheckBoxます。

そうは言っても、ここには2つの解決策があります。

  • 簡単な解決策は、次のように使用すること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())
    

    代わりに、上記の式 ( type を持つ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 に答える