Components 常見於各種javascript 的frameworks。譬如react components, ember components, vue components。就會常常有所謂的parent-child communication。如果有好幾層,就會有deeply nested problem
如果你要把elm寫成parent components 和child components,讓他們之間的update溝通,其實也是可以的。但是這不是正確的官方寫法。官方的解法是推薦使用unidirectional data flow,也就是說只有一個update, view, 和model,建構而成的TEA(The Elm Architecture)。
when view is large, subdivided it 寫幾個helper fucntion,把 view
變成幾個小的function
viewSearchResult : SearchResult -> Html Msg
viewErrorMessage: Maybe String -> Html msg
viewOptions: SearchOptions -> Html OptionsMsg
把 update
和 model
保持一樣的。 沒有變大變肥的,我們就不要動;動那些變大變肥的。
如果 Model
變大,我們就像上一篇那樣,把 Model
變小。 如果 update
變大,我們就像上一篇那樣,把 update
變小。
這樣說其實還是很空泛,除非自己有動手寫過。但自己動手寫可能寫三十天鐵人賽都結束了,這還沒寫完,還有很多東西要介紹耶。我們來看這個RealWorld example app
,
其實還有很多前後端框架,但都是同一個例子,對於學習上來說幫助很大,今天我們要來看的是Richard
Feldman寫的 elm。實際執行起來長這個樣子:demo。詳細的開發過程
我們來看 Main.elm
的一小段:
type Msg
= SetRoute (Maybe Route)
| HomeLoaded (Result PageLoadError Home.Model)
| ArticleLoaded (Result PageLoadError Article.Model)
| ProfileLoaded Username (Result PageLoadError Profile.Model)
| EditArticleLoaded Slug (Result PageLoadError Editor.Model)
| HomeMsg Home.Msg
| SettingsMsg Settings.Msg
| SetUser (Maybe User)
| LoginMsg Login.Msg
| RegisterMsg Register.Msg
| ProfileMsg Profile.Msg
| ArticleMsg Article.Msg
| EditorMsg Editor.Msg
....
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
updatePage (getPage model.pageState) msg model
看到了嗎?在update裡的 Msg
還是一大包,但是只有一個 update
, update
有很多helper function
還有另外一種分類法,你也可以試試:How I structure elm apps
他把elm app放成這樣:
src
├── App.elm
├── Types.elm
├── State.elm
├── View.elm
├── FrontPage
│ ├── Rest.elm
│ ├── State.elm
│ ├── Types.elm
│ └── View.elm
├── Login
│ ├── Rest.elm
│ ├── State.elm
│ ├── Types.elm
│ └── View.elm
└── Registration
├── Rest.elm
├── State.elm
├── Types.elm
└── View.elm
也就是有App, Types, State, View。main放在App.elm,init和update放在
State.elm;各種的types放在Types.elm,其他的View依位置存放。看人嘍,提供各位參考