从子组件更改全局状态

Changing global state from child component

我想知道使用 TEA 从子组件修改全局状态的首选方法是什么。

我的用例在任何 json 请求正在进行时显示全局 loading indicator

google 搜索找到了我 this article,但我不是 100% 这是最好的解决方案。还有其他建议吗?


更多背景知识:

我有一个包含各种组件和一个 "Loader" 组件的 SPA。加载器组件应该处理视图之间的转换。

例如,假设我有 3 个视图:(A) 仪表板 (B) 帐户 (C) 交易详情。

当用户在 (A) 上并单击我希望 (A) 发送的事务时,通知加载程序它需要加载事务资源,完成后更新浏览器位置,以便根组件可以处理路由。

加载程序在加载资源时应在页面顶部显示一个加载栏。完成后,它将更新位置栏,因此根组件可以处理路由。

本质上,我要避免的是在加载资源之前显示 (C) 页面。

下面的结构有望助您一臂之力。

更多关于scaling Elm here (highly recommended)

在下面的示例中,您将所有数据都保存在顶级模型中,还有您的消息。

这样的设置没有父子关系。所有视图都使用相同的顶级模型,并且所有视图都产生相同类型的消息。

此示例在交易进入后立即导航到交易页面。

type alias Model = 
  { accounts: List Account
  , transactions: Transactions
  , currentPage : Page
  , message : String
  }

type Transactions = Idle | Loading | GotEm (List Transaction)

type Page = DashboardPage | AccountsPage | TransactionsPage

type Msg = ShowDashboard | ShowAccounts | ShowTransactions | GotJSONData

update msg model = 
  case msg of
    ShowTransactions ->
      case model.transactions of
        GotEm transactions ->
          { model 
          | currentPage = TransactionsPage 
          , message = ""
          } ! []

        Idle ->
          { model 
          | currentPage = DashboardPage
          | transactions = Loading
          , message = "Loading transactions" 
          } ! [ API.getTransactions model GotJSONData ]

        Loading ->
          model ! []

    GotJSONData transactions ->
      { model 
      | transactions = GotEm transactions 
      , message = ""
      , currentPage = TransactionsPage
      }

view model =
  case model.currentPage of
    DashboardPage ->
      DashboardPage.view model

-- DASHBOARD module

view model =
  div []
    [ ...
    , button [ onClick ShowTransactions ] [ text "Show transactions"]
    ]