Elm - 命令


在前面的章节中,我们讨论了 Elm 架构的各个组件及其功能。用户和应用程序使用消息相互通信。

考虑一个示例,其中应用程序需要与其他组件(如外部服务器、API、微服务等)通信来服务用户请求。这可以通过使用 Elm 中的命令来实现。消息和命令不是同义词。消息代表最终用户和应用程序之间的通信,而命令代表 Elm 应用程序如何与其他实体通信。命令被触发以响应消息。

下图显示了复杂的 Elm 应用程序的工作流程 -

工作流程

用户与视图交互。该视图根据用户的操作生成适当的消息。更新组件接收该消息并触发命令。

句法

定义命令的语法如下 -

type Cmd msg

视图生成的消息将传递给命令。

插图

以下示例向 API 发出请求并显示 API 的结果。

应用程序接受用户的号码,并将其传递给 Numbers API。此 API 返回与号码相关的事实。

该应用程序的各个组件如下 -

Http模块

Elm 的 Http 模块用于创建和发送 HTTP 请求。该模块不是核心模块的一部分。我们将使用 elm 包管理器来安装这个包。

应用程序编程接口

在此示例中,应用程序将与 Numbers API 进行通信 - “ http://numbersapi.com/#42 ”。

看法

应用程序的视图包含一个文本框和一个按钮。

view : Model -> Html Msg
view model =
   div []
      [ h2 [] [text model.heading]
      ,input [onInput Input, value model.input] []
      , button [ onClick ShowFacts ] [ text "show facts" ]
      , br [] []
      , h3 [][text model.factText]
      ]

模型

Model 代表用户输入的值以及 API 将返回的结果。

type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

信息

该应用程序有以下三个消息 -

  • 显示事实
  • 输入
  • 新事实到来

单击“显示事实”按钮后,“显示事实”消息将传递到更新方法。当用户在文本框中键入某些值时,输入消息将传递给更新方法。最后,当收到Http服务器响应时,将传递NewFactArrived消息进行更新。

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

更新

update 方法返回一个元组,其中包含模型和命令对象。当用户单击“显示事实”按钮时,消息将传递到更新,然后更新调用 NumbersAPI。

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
   case msg of
      Input newInput ->
      (Model "NumbersApi typing.." "" newInput ,Cmd.none)
      ShowFacts ->
         (model, getRadmonNumberFromAPI model.input)

      NewFactArrived (Ok newFact) ->
         (Model "DataArrived" newFact "", Cmd.none)

      NewFactArrived (Err _) ->
      (model, Cmd.none)

辅助功能

辅助函数getRandomNumberFromAPI调用 NumbersAPI 并将用户输入的数字传递给它。API返回的结果用于更新模型。

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
         "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)
先生。没有。 方法 签名 描述
1 Http.getString getString : 字符串 -> 请求字符串 创建 GET 请求并将响应正文解释为字符串。
2 HTTP发送 发送:(结果错误 a -> 消息) -> 请求 a -> Cmd 消息 发送 Http 请求。

主要的

这是Elm项目的入口点。

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

把它们放在一起

步骤 1 - 创建文件夹 CommandApp 和文件 CommandDemo.elm。

步骤 2 - 使用命令elm package install elm-lang/http安装 http 模块。

步骤 2 - 输入 CommandDemo.elm 的内容,如下所示 -

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

-- MODEL
type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

init : (Model, Cmd Msg)
init =
   ( Model "NumbersAPI" "NoFacts" "42"-- set model two fields
   , Cmd.none -- not to invoke api initially
   )

-- UPDATE

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
   case msg of
      Input newInput ->
      (Model "NumbersApi typing.." "" newInput ,Cmd.none)
      ShowFacts ->
         (model, getRadmonNumberFromAPI model.input)

      NewFactArrived (Ok newFact) ->
         (Model "DataArrived" newFact "", Cmd.none)

      NewFactArrived (Err _) ->
         (model, Cmd.none)

- VIEW

view : Model -> Html Msg
view model =
   div []
      [ h2 [] [text model.heading]
      ,input [onInput Input, value model.input] []
      , button [ onClick ShowFacts ] [ text "show facts" ]
      , br [] []
      , h3 [][text model.factText]
      ]

-- SUBSCRIPTIONS

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

-- HTTP

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
      "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)

步骤 4 - 触发命令。

C:\Users\dell\elm\CommandApp> elm make .\CommandDemo.elm

这将生成如下所示的 html 文件。

生成html