2

私がやりたいのは、フォーカスされているときに詳細を表示し、フォーカスされていないときに要約を表示するフィールドを設定することです。例えば。

a)。フォーカスを失ったとき (ぼかしを取得しますか?)、値を (状態?) マップに保存し、その値を古い値の関数 (つまり、集計値) に変更します。

b)。フォーカスを取得したら、集計値をマップに保存した古い値に置き換えます

これを行う方法がわかりませんが、おそらく状態モナドと UI モナドが必要だと思います。私の試みは:

renderField :: Map->Int->UI (Element, Map)
renderField vs ix = do
    input <- UI.input  
    on UI.blur input $ \_ -> void $ do
        fieldValue <- get value input
        let newVs = insert ix fieldValue vs
        return input # set UI.value (calcNewValue fieldValue)
    on UI.focus input $ \_ -> void $ do
        let savedValue = findWithDefault "" ix vs
        return input # set UI.value savedValue
    return (input, newVs)

しかし、私はこのマップを機能させることができません - それはすべての呼び出しを追跡する必要があるからです.... 私はそれが State モナドか何かであるべきだと思いますか?

ありがとう。

N

4

1 に答える 1

2

実際、状態を追跡する必要があります。

ただし、コールバック関数を使用しているため、通常のパターンs -> (a,s)(状態モナド) はここでは適用されません。これらには、別のパターンが必要です。

伝統的な命令型スタイルでは、ここで変更可能な変数、たとえば an を使用しますIORef。インデックスを追跡する必要がなくなったことに注意してくださいIORef。 は大きな可変マップのインデックスと考えることができます。

renderField :: UI Element
renderField = do
    input <- UI.input
    state <- liftIO $ newIORef

    on UI.blur input $ \_ -> do
        fieldValue <- get value input
        liftIO $ writeIORef state fieldValue    
        element input # set UI.value (calcNewValue fieldValue)

    on UI.focus input $ \_ -> do
        savedValue <- liftIO $ readIORef state
        element input # set UI.value savedValue

    return input

または、Threepenny で関数型リアクティブ プログラミング (FRP) を使用することもできます。threepenny-guiAPI はまだ予備的なものであることに注意してください。次のコードはversionに固有のもの0.4.*です。

renderField :: UI Element
renderField = do
    input  <- UI.input

    bValueUser <- stepper "" $ UI.valueChange input
    bState     <- stepper "" $ bValueUser <@ UI.blur input
    bValue     <- stepper "" $ fmap head $ unions
        [ (calcNewValue <$> bValueUser) <@ UI.blur input
        , bState <@ UI.focus input
        ]
    element input # sink UI.value bValue 

繰り返しになりますが、このコードにはまだいくつかの微妙な点や欠点がありますが、これが私が目指したい一般的な方向性です。FRP に関する予備情報と、それが GUI 開発にどのように適用されるかについては、ドキュメンテーションを参照してください。

何かをすぐに終わらせる必要がある場合は使い慣れたソリューション ( IORef) を使用し、十分な時間がある場合は FRP ソリューションを検討することをお勧めします。サンプル コードでは、主に FRP スタイルを使用しています。

(開示: 私は Threepenny の作者です。)

于 2014-01-04T10:14:27.683 に答える