2017-04-04 49 views
1

這裏的短版本:柯里(部分功能)的定製事件監聽器

我有一個函數:

onClick : String -> Bool -> (State -> msg) -> Options.Property c msg 
onClick name isReversed toMsg = 
    Options.on "click" <| Json.succeed <| 
    toMsg (State name isReversed) 

我想改變的功能如下:

onClick : String -> Bool -> (State -> msg) -> (Maybe msg -> Options.Property c msg) 

換句話說,我希望它返回一個部分函數,​​它需要一個Maybe味精。但是,我不知道該怎麼做!幫助將不勝感激。

這裏的長版本:

我想建立一個它採用榆樹MDL包,允許自定義事件監聽器列標題榆樹排序表的包中的「叉」。可排序表包(顯然)在列標題上應用事件監聽器,該列標題按該列對錶進行排序。

不幸的是,你不能在同一個元素上有兩個'onClick'監聽器,所以我決定做的是將自定義消息作爲參數傳遞給排序消息,然後將它作爲命令發送從排序更新。對不起,如果你不熟悉這個軟件包,並且聽起來像是巨無霸,我只是想給出我的問題的背景。

的排序表的包的開發人員創建一個自定義事件監聽器,看起來像這樣:

onClick : String -> Bool -> (State -> msg) -> Attribute msg 
onClick name isReversed toMsg = 
    E.on "click" <| Json.map toMsg <| 
    Json.map2 State (Json.succeed name) (Json.succeed isReversed) 

我已經改變了它一下使用MDL自定義事件監聽器,並使其(在我意見),稍微更具可讀性:

onClick : String -> Bool -> (State -> msg) -> Options.Property c msg 
onClick name isReversed toMsg = 
    Options.on "click" <| Json.succeed <| 
    toMsg (State name isReversed) 

正如我已經說過了,我想它是這樣的:

onClick : String -> Bool -> (State -> msg) -> (Maybe msg -> Options.Property c msg) 

但是,如果您對包裝非常熟悉,並且有任何其他建議,請單擊某一列來使用自定義消息,請向他們建議!我真的不知道我在做什麼。

較長的版本:

在組件的視圖代碼中,有一個變量theadDetails它看起來像這樣:

theadDetails = 
customizations.thead (List.map (toHeaderInfo state toMsg columns) 

statetoMsgcolumns都來自於配置在該項目的主要查看代碼。 toMsg是在主更新中處理的Msg(組件不記錄其自己的狀態)。

toHeaderInfo看起來像這樣:

toHeaderInfo : State -> (State -> msg) -> ColumnData data msg -> (String, Status, Options.Property c msg) 
toHeaderInfo (State sortName isReversed) toMsg { name, sorter } = 
    case sorter of 
     None -> 
      (name, Unsortable, onClick sortName isReversed toMsg) 

     Decreasing _ -> 
      (name, Sortable (name == sortName), onClick name False toMsg) 

     IncOrDec _ -> 
      if name == sortName then 
       (name, Reversible (Just isReversed), onClick name (not isReversed) toMsg) 
      else 
       (name, Reversible Nothing, onClick name False toMsg) 

這基本上是其中將要包括在每個元件中的數據被呈現。所有關於Statesorter的東西都與每列的排序方式和當前順序有關。但是你看,在這裏onClick被調用並通過了必要的參數。

正如你在theadDetails看到,該信息隨後被傳遞給一個函數,customizations.tHead它看起來像這樣:

defaultCustomizations : Customizations data msg c 
defaultCustomizations = 
    { tableAttrs = [] 
    , caption = Nothing 
    , thead = simpleThead 
    , tfoot = Nothing 
    , tbodyAttrs = [] 
    , rowAttrs = simpleRowAttrs 
    } 


simpleThead : List (String, Status, Options.Property { numeric : Bool, sorted : Maybe Table.Order } msg) -> HtmlDetails {} msg 
simpleThead headers = 
    HtmlDetails [] (List.map simpleTheadHelp headers) 


simpleTheadHelp : (String, Status, Options.Property { numeric : Bool, sorted : Maybe Table.Order } msg) -> Html msg 
simpleTheadHelp (name, status, onClick) = 
    let 
     check = 
      Debug.log "status" status 

     attrs = 
      case status of 
       Unsortable -> 
        [] 

       Sortable selected -> 
        if selected then 
         [ onClick 
         , Options.css "color" "rgb(0,0,0)" 
         ] 
        else 
         [ onClick ] 

       Reversible Nothing -> 
        [ onClick 
        ] 

       Reversible (Just isReversed) -> 
        [ onClick 
        , Options.css "color" "rgb(0,0,0)" 
        ] 
    in 
     Table.th attrs [ Html.text name ] 

這正是在這裏,我想傳遞的最後一個參數。所以simpleTheadHeald將成爲:

simpleTheadHelp : (String, Status, Options.Property { numeric : Bool, sorted : Maybe Table.Order } msg) -> Html msg 
simpleTheadHelp (name, status, onClick) = 
    let 
     check = 
      Debug.log "status" status 

     attrs = 
      case status of 
       Unsortable -> 
        [] 

       Sortable selected -> 
        if selected then 
         [ onClick Nothing 
         , Options.css "color" "rgb(0,0,0)" 
         ] 
        else 
         [ onClick Nothing ] 

       Reversible Nothing -> 
        [ onClick Nothing 
        ] 

       Reversible (Just isReversed) -> 
        [ onClick Nothing 
        , Options.css "color" "rgb(0,0,0)" 
        ] 
    in 
     Table.th attrs [ Html.text name ] 

然而,這給了我一個錯誤說的onClick不是一個函數(因爲在類型定義它不期待一個參數)。

對不起,我做這樣的不好解釋嘍!我真的很想弄明白,所以我很感激耐心。

回答

1

我不熟悉的包裝,所以如果我失去了你的問題或事情告訴你,你已經知道的東西,我很抱歉。在榆樹

功能被自動令行禁止。所有你需要做的是通過函數一組不完整的參數,你會得到一個函數,其餘的參數(S)。因此,這將是您的函數簽名:

onClick : String -> Bool -> (State -> msg) -> Maybe msg -> Options.Property c msg 
onClick name isReversed toMsg maybeMsg = 

然後您使用所有參數編寫函數,而不用擔心部分應用程序。調用該函數只有前三個參數,如:

onClick "myName" True MyMsg 

會自動返回功能與此簽名:

newFunction : Maybe msg -> Options.Property c msg 

您不需要做任何事情。

+1

謝謝!這似乎已經成功了。天啊,我嘗試各種瘋狂的事情,極大地知道它是如此簡單。 –