2017-01-28 8 views
1

Я пытался продлить нажмите и перетащите пример, чтобы получить несколько квадратов вместо того, чтобы только один http://elm-lang.org/examples/dragКак увеличить пример перетаскивания мыши Elm, чтобы включить несколько квадратов?

Соответствующая часть является обновление:

type Msg 
    = DragStart Position 
    | DragAt Position 
    | DragEnd Position 


update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    (updateHelp msg model, Cmd.none) 


updateHelp : Msg -> Model -> Model 
updateHelp msg ({position, drag} as model) = 
    case msg of 
    DragStart xy -> 
     Model position (Just (Drag xy xy)) 

    DragAt xy -> 
     Model position (Maybe.map (\{start} -> Drag start xy) drag) 

    DragEnd _ -> 
     Model (getPosition model) Nothing 



-- SUBSCRIPTIONS 


subscriptions : Model -> Sub Msg 
subscriptions model = 
    case model.drag of 
    Nothing -> 
     Sub.none 

    Just _ -> 
     Sub.batch [ Mouse.moves DragAt, Mouse.ups DragEnd ] 

Я изменил вид так, чтобы это было SVG вместо Div. Модель такая же (что является точкой продажи архитектуры Elm).

Дилемма заключается в том, как изменить модель и перетащить архитектуру, чтобы передать информацию о которой квадрат быть нажата и переехал

type alias Model = 
    { position : Position 
    , drag : Maybe Drag 
    } 


type alias Drag = 
    { start : Position 
    , current : Position 
    } 

Вместо этого я изменил эту модель, чтобы включать в себя абстракции под названием Tile, который никуда не ходил:

type alias Model = { a: Tile, b: Tile, c: Tile } 

type alias Tile = 
    { position : Position 
    , drag : Maybe Drag 
    } 

type alias Drag = 
    { start : Position 
    , current : Position 
    } 

Я думал, что было бы просто слить все события обновления, чтобы запомнить, какой квадрат был нажат. Но я полностью потерян и сделан на сегодня.

ответ

1

Elm не позволяет вам перебирать запись. Так что хорошим началом было бы поставить плитки в Dict, что упростит доступ и обновление отдельных фрагментов.
Вам также нужно будет отслеживать, какая из ваших плиток перетаскивается. И в любой момент можно вытащить только одну плитку. Таким образом, внутри модели Drag кажется приятным местом.

type alias Model = 
    { tiles : Dict Int Tile 
    , draggedTile : Maybe Drag 
    } 

type alias Tile = Position 

type alias Drag = 
    { draggedTileId : Int 
    , start : Position 
    , current : Position 
    } 

Ваше DragStart сообщения, то необходимо будет также включать идентификатор плитки тащит:

type Msg 
    = DragStart Int Position 
    | DragAt Position 
    | DragEnd Position 

Затем в update всякий раз, когда вы получаете DragStart сообщения, вы установите draggedTile, и магазин id плитки вы получите.
Когда приходит сообщение DragAt или DragEnd, вы только читаете позицию и обновляете перетаскивание (и плитка при завершении перетаскивания).

В вашей view функции включают в себя
List.map viewTile (Dict.toList model.tiles)

И добавить помощника, чтобы сделать каждую плитку:

viewTile : (Int, Tile) -> Html Msg 
viewTile (id, tile) = 
    ... 

Надеюсь, это вас происходит в правильном направлении ..