2016-09-27 15 views
7

मैं एक उच्च आदेश समारोह कार्यों बनाने के लिए केवल एक विशिष्ट कुंजी कोड पर कब्जा करने के बनाने के लिए कोशिश कर रहा हूँ के लिए एल्म उच्च आदेश कार्यों का उपयोग करना। यह कोड इवान के "ऑनएंटर" फ़ंक्शन पर उनके टूडोवैक कार्यान्वयन से प्रेरित है जो केवल एंटर फ़ंक्शन को कैप्चर करता है।कीबोर्ड की घटनाओं

onKeyCode : Int -> Msg -> Attribute Msg 
onKeyCode keycode msg = 
    let 
     captureKey code = 
      if code == keycode then 
       msg 
      else 
       NoOp 
    in 
     on "keydown" (Json.map captureKey keyCode) 

onEnter = onKeyCode 13 
onEsc = onKeyCode 27 

और अब मैं एक इनपुट घटक है कि जोड़ने के लिए दर्शक में हैं:

input 
[ class "edit" 
, id ("todo-" ++ toString item.uid) 
, value item.message 
, onInput (UpdateItem item.uid) 
, onBlur (SwitchEditTodo item.uid False) 
, onEnter (SwitchEditTodo item.uid False) 
, onEsc (UndoEditTodo item.uid) 
] 
[] 

यदि मैं केवल अपेक्षा के अनुरूप onEnter कोड काम करेंगे, लेकिन अगर मैं onEsc जोड़ने के लिए, onEnter कोड कभी निष्पादित नहीं किया जाता है। मैं गलती कहां कर रहा हूँ? क्या यह उच्च कार्य फ़ंक्शन संदर्भ या अलग-अलग कार्यों में एकाधिक मानों के साथ "चालू" मैपिंग के साथ एक समस्या है?

उत्तर

8

आप इनपुट तत्व करने के लिए दो onkeydown गुण जोड़ रहे हैं, और उनमें से केवल एक जीत सकते हैं। सूची में दूसरा सबसे पहले ओवरराइट करता है। दृश्यों के पीछे addEventListener का उपयोग करना था, यह मामला नहीं होगा, लेकिन अभी के लिए हम इसे थोड़ा अलग दृष्टिकोण से हल कर सकते हैं।

onKeysDown : List (Int, Msg) -> Attribute Msg 
onKeysDown keys = 
    let 
    captureKey code = 
     List.filterMap (\(k, m) -> if k == code then Just m else Nothing) keys 
     |> List.head 
     |> Maybe.withDefault NoOp 
    in 
    on "keydown" (Json.map captureKey keyCode) 

फिर आप इस तरह विशिष्ट कुंजी से निपटने के लिए आशुलिपि कार्यों लिख सकते हैं::

आप एक onKeysDown समारोह है कि संभव कुंजी कोड की एक सूची और संदेश वे इस तरह आह्वान चाहिए स्वीकार करता है लिख सकता है

enter msg = (13, msg) 
esc msg = (27, msg) 

और अब आप इस तरह आपके विचार में इसका इस्तेमाल कर सकते हैं:

input 
    [ ... 
    , onKeysDown 
     [ enter <| SwitchEditTodo item.uid False 
     , esc <| UndoEditTodo item.uid 
     ] 
    ] 

यह काम करता है, क्योंकि यह एक एकल keydown ईवेंट हैंडलर विशेषता उत्पन्न करता है। और जब आप उच्च ऑर्डर फ़ंक्शन के लिए पूर्वनिर्धारित ट्यूपल को प्रतिस्थापित करते हैं, तो यह आपको अभी भी पठनीय कोड के रूप में देता है।

+2

अपनी टिप्पणी से, मैं समझता हूँ कि इस ओवरराइटिंग प्रभाव HTML/जावास्क्रिप्ट से उभर एक पक्ष प्रभाव है, क्योंकि मैं घटनाओं मैं सब के बाद सिर्फ कवर जो मुझे करने की अनुमति देता के तहत जावास्क्रिप्ट एपीआई बोल रहा हूँ "पर" कई बनाया है, भले ही खुद को ओवरराइट करें। –

+4

सही है, यह एल्म की एक सीमा (हालांकि कुछ चेतावनी अच्छा होगा) एक ही नाम के कई एचटीएमएल विशेषताओं में से एक सीमा, नहीं है। यदि आप कच्चे एचटीएमएल में एक ही काम करने की कोशिश करते हैं तो आपको वही समस्या दिखाई देगी –

संबंधित मुद्दे