触发事件时获取 ID 属性(elm v0.19.1)
Getting ID attribute when event is triggered (elm v0.19.1)
我有两个 div
html 元素(具有 contenteditable
属性),我想在 keypress
时获取元素的 de id
属性被触发(onblur
事件)。
这是我当前的代码(它不起作用,我添加了任何注释):
module Mytest exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Json.Decode as Json
import Debug
type alias Model =
{ div1 : String
, div2 : String
}
initialModel : Model
initialModel =
{ div1 = "test1"
, div2 = "test2"
}
init : () -> ( Model, Cmd Msg )
init () =
( initialModel, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ div [ id "div1", contenteditable True, onKeyPress KeyPressed ] [ text model.div1 ]
, div [ id "div2", contenteditable True, onKeyPress KeyPressed ] [ text model.div2 ]
]
type Msg
= KeyPressed Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed code ->
let
-- is there any way to use Debug.log without let block?
a = Debug.log "div1 event" code
in
-- keypressed on div1 should be update div1 field model
-- the same to div2
({model | div1 = String.fromInt code}, Cmd.none)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
onKeyPress : (Int -> msg) -> Attribute msg
onKeyPress tagger =
on "keypress" (Json.map tagger keyCode)
编辑:
以下示例不会触发 div contenteditable
中的事件:
onInput : (String -> msg) -> Attribute msg
onInput tagger =
on "input" (Json.map tagger keyCode)
onBlur : (String -> msg) -> Attribute msg
onBlur tagger =
on "blur" (Json.map tagger targetValue)
onInput : (String -> msg) -> Attribute msg
onInput tagger =
stopPropagationOn "DOMCharacterDataModified" <|
Json.map alwaysStop (Json.map tagger (Debug.log "bbb" targetValue))
alwaysStop : a -> (a, Bool)
alwaysStop x =
(x, True)
但是,在 javascript 中有效:http://jsfiddle.net/MBags/
除非你的例子中没有明显的额外限制,你可以向 KeyPressed
添加一个额外的参数并通过它传递 id:
type Msg
= KeyPressed String Int
view : Model -> Html Msg
view model =
div []
[ div [ id "div1", contenteditable True, onKeyPress (KeyPressed "div1") ] [ text model.div1 ]
, div [ id "div2", contenteditable True, onKeyPress (KeyPressed "div2") ] [ text model.div2 ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed id code ->
-- Now you have the id
但是,您可能一开始就不应该依赖字符串 ID,因为字符串类型的数据非常容易出错。理想情况下,每个组件都有单独的 Msg
变体:
type Msg
= Div1KeyPressed Int
| Div2KeyPressed Int
或者,如果您需要更多的活力,您可以使用自定义 Id
类型:
type Id
= Div1
| Div2
type Msg
= KeyPressed Id Int
view : Model -> Html Msg
view model =
div []
[ div [ contenteditable True, onKeyPress (KeyPressed Div1) ] [ text model.div1 ]
, div [ contenteditable True, onKeyPress (KeyPressed Div2) ] [ text model.div2 ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed Div1 code ->
-- update model.div1
KeyPressed Div2 code ->
-- update model.div2
我有两个 div
html 元素(具有 contenteditable
属性),我想在 keypress
时获取元素的 de id
属性被触发(onblur
事件)。
这是我当前的代码(它不起作用,我添加了任何注释):
module Mytest exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Json.Decode as Json
import Debug
type alias Model =
{ div1 : String
, div2 : String
}
initialModel : Model
initialModel =
{ div1 = "test1"
, div2 = "test2"
}
init : () -> ( Model, Cmd Msg )
init () =
( initialModel, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ div [ id "div1", contenteditable True, onKeyPress KeyPressed ] [ text model.div1 ]
, div [ id "div2", contenteditable True, onKeyPress KeyPressed ] [ text model.div2 ]
]
type Msg
= KeyPressed Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed code ->
let
-- is there any way to use Debug.log without let block?
a = Debug.log "div1 event" code
in
-- keypressed on div1 should be update div1 field model
-- the same to div2
({model | div1 = String.fromInt code}, Cmd.none)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
onKeyPress : (Int -> msg) -> Attribute msg
onKeyPress tagger =
on "keypress" (Json.map tagger keyCode)
编辑:
以下示例不会触发 div contenteditable
中的事件:
onInput : (String -> msg) -> Attribute msg
onInput tagger =
on "input" (Json.map tagger keyCode)
onBlur : (String -> msg) -> Attribute msg
onBlur tagger =
on "blur" (Json.map tagger targetValue)
onInput : (String -> msg) -> Attribute msg
onInput tagger =
stopPropagationOn "DOMCharacterDataModified" <|
Json.map alwaysStop (Json.map tagger (Debug.log "bbb" targetValue))
alwaysStop : a -> (a, Bool)
alwaysStop x =
(x, True)
但是,在 javascript 中有效:http://jsfiddle.net/MBags/
除非你的例子中没有明显的额外限制,你可以向 KeyPressed
添加一个额外的参数并通过它传递 id:
type Msg
= KeyPressed String Int
view : Model -> Html Msg
view model =
div []
[ div [ id "div1", contenteditable True, onKeyPress (KeyPressed "div1") ] [ text model.div1 ]
, div [ id "div2", contenteditable True, onKeyPress (KeyPressed "div2") ] [ text model.div2 ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed id code ->
-- Now you have the id
但是,您可能一开始就不应该依赖字符串 ID,因为字符串类型的数据非常容易出错。理想情况下,每个组件都有单独的 Msg
变体:
type Msg
= Div1KeyPressed Int
| Div2KeyPressed Int
或者,如果您需要更多的活力,您可以使用自定义 Id
类型:
type Id
= Div1
| Div2
type Msg
= KeyPressed Id Int
view : Model -> Html Msg
view model =
div []
[ div [ contenteditable True, onKeyPress (KeyPressed Div1) ] [ text model.div1 ]
, div [ contenteditable True, onKeyPress (KeyPressed Div2) ] [ text model.div2 ]
]
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
KeyPressed Div1 code ->
-- update model.div1
KeyPressed Div2 code ->
-- update model.div2