在Elm中导入模块和HTTP请求

时间:2016-08-10 17:33:28

标签: elm

我和榆树玩了一下,但我不确定如何妥善解决这个问题。目的是每次通过保存方法创建项目时调用外部API。

编译器说:

The type annotation for `update` does not match its definition.

The type annotation is saying:
 
     Main.Msg -> Main.Model -> ( Main.Model, Cmd Main.Msg )
 
 But I am inferring that the definition has this type:
 
     Main.Msg -> Main.Model -> ( Main.Model, Cmd Decoder.Msg )at line 100 col 10

Main.elm

    bla bla bla

    import Components.Decoder as Decoder exposing (..)

    type alias Item =
        { name : String
        , qty : Int
        }


    type alias Model =
        { name : String
        , items : List Item
        , images : Images
        }


    type Msg
        = Save
        | Input String
        | Delete Item
        | Clear
        | Sum Item Int
        | NoOp

    bla bla bla


    update : Msg -> Model -> ( Model, Cmd Msg )
         update msg model =
          case msg of
              Save ->
              --( add model, Cmd.none )
              ( add model, fetchCmd )

              Input name ->
                ( { model | name = name }, Cmd.none )

               Sum item number ->
                 ( sum model item number, Cmd.none )

              Delete item ->
                ( delete model item, Cmd.none )

               Clear ->
                 ( { model | name = "" }, Cmd.none )

               NoOp ->
               ( model, Cmd.none )

Decoder.elm

module Components.Decoder exposing (..)

import Http exposing (..)
import Json.Decode as Decode exposing (Decoder, (:=))
import String
import Task exposing (Task)


type Msg
    = Fetch
    | FetchSucceed Images
    | FetchFail Http.Error


type alias Model =
    { id : Int
    , albumId : Int
    , title : String
    , url : String
    , thumbnailUrl : String
    }


type alias Images =
    List Model


url : String
url =
    "https://jsonplaceholder.typicode.com/photos"


stringToInt : Decoder String -> Decoder Int
stringToInt d =
    Decode.customDecoder d String.toInt


decoder : Decoder Model
decoder =
    Decode.object5 Model
        ("id" := Decode.string |> stringToInt)
        ("albumId" := Decode.string |> stringToInt)
        ("title" := Decode.string)
        ("url" := Decode.string)
        ("thumbnailUrl" := Decode.string)


decoderAll : Decoder Images
decoderAll =
    Decode.list decoder


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Fetch ->
            ( model, fetchCmd )

        FetchSucceed images ->
            ( model, Cmd.none )

        FetchFail _ ->
            ( model, Cmd.none )


fetchTask : Task Http.Error Images
fetchTask =
    Http.get decoderAll url


fetchCmd : Cmd Msg
fetchCmd =
    Task.perform FetchFail FetchSucceed fetchTask


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none

1 个答案:

答案 0 :(得分:1)

我不建议过早地将您的应用程序拆分为单独的组件。

您遇到的问题主要是由于Decoder.fetchCmd导致Decoder.Msg导致您Main.update内部使用Decoder

简单

如果您不打算在其他任何地方重复使用Main.elm,我建议您将逻辑重新放入Main.update

  • Decoder.updateMain.Msg
  • 合并
  • Decoder.MsgDecoder.Model
  • 合并
  • Main.Model必须是update
  • 的一部分
  • 在单个Http.get函数
  • 中处理整个事情

可重复使用

无论您想从服务器检索哪些数据,如果您计划将某些数据输出给用户,则应该将其存储在应用程序状态中。

如果您真的想要一个可重复使用的组件来发送update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of Save -> -- Map Decoder.msg to Main.DecoderMsg ( add model, Cmd.map DecoderMsg fetchCmd ) DecoderMsg msg -> let -- Pass the message and handle the update. ( fetchedAlbumList, decoderCmd ) = Decoder.update msg model.albumList in -- Put retrieved data in the application state { model | albumList = fetchedAlbumList } ,您将需要执行以下操作:

(Board[i][j] == 0) ? "  " : "\u2588\u2588";