@Mark this is a pattern I've been exploring recently. An area that I haven't found a solution to is keeping the view model in sync with the shared models. For instance, let's say I have a view with a list of checkboxes next to each user. The state for the checkboxes would be kept in the view model, but then I need to manage adding/removing checkboxes as the list of users changes. Currently I handle this by having a default state for the checkbox which is used until a user actually clicks on a checkbox at which point the state is added to the view model. This works but is semantically awkward and doesn't take care of removing the checkbox state if a user is removed from the shared list. https://github.com/elm-lang/html/issues/19 provides a potential avenue for cleanup, but even then the lifecycle seems a little awkward.
I wonder if you have a different approach for this problem? On Sunday, 23 October 2016 21:29:23 UTC+2, Mark Hamburg wrote: > > We're just getting into having an app where this is likely to matter, but > if you have multiple views onto the same data, then the pattern that would > seem to apply is to have a single data model and multiple view models. The > data model handles the shared part. The view models handle things specific > to the particular view — e.g., is a spin down open, what's the scroll > position, etc. The view functions would take the data model and their > particular view model as parameters and would generate appropriately tagged > messages back. This avoids significant nesting while still providing some > structure to keep pieces that can be separated separate. > > There are then a couple ways to structure the multiple view models. One is > to have a view selector but keep all of the view models alive all the time. > The benefit of this is that when you switch back to a view, it will > remember where you were. The downside is that one is carrying around — and > potentially updating if the view model depends on the data model — an > increasing number of view models if you have an increasing number of views. > The alternative is to put the view models into a union type and have one > model entry that serves as both view selector and view model storage. This > keeps things lighter weight but means that you have nowhere to maintain > context when switching back and forth. > > Above all of this, the other key subdivision we are making in our SPA and > that I would recommend having seen where other programmers often first > head, is having a top layer that handles overall app state — e.g., logged > in v not logged in — as a type union. This can also often be where the > routing logic plugs in. People who haven't spent a lot of time thinking in > terms of type unions tend to load their model up with a lot of fields that > only have meaning in certain states. This then leads to more invariants > about the state that can't be enforced by the compiler. Breaking things up > into different type cases for different states allows one to make more bad > states simply impossible. For example, our logging in state has a > RemoteData.WebData User reflecting whether we've gotten valid user data > back from the server but our logged in state simply has a User. The top > level event dispatcher works with the following type signature on the log > in state update: > > update : Login.Msg -> Login.Model -> ( Login.Model, Cmd Login.Msg, Maybe > User ) > > > After each call to update, it can check to see whether we now have a valid > user and if so switch to the logged in state, initializing it with the > supplied user. > > This isn't as flat as some people go, but it doesn't spread things out > into lots of components and the top layer(s) are pretty simple. > > Mark > > > On Sun, Oct 23, 2016 at 11:39 AM, Francois <[email protected] > <javascript:>> wrote: > >> Hi, >> >> I'm really new to Elm. I'm not good enough to propose a guideline about >> Elm app structure but as a novice a guideline can help lots of people. >> >> I worked / works on a large angular application and John Papa Styleguide >> has been really helpful at the beginning. >> So writing a community guideline can be a great resource. (there is >> another thread inter component that seems related) >> >> For example, on the server side, structuring domain core by features is >> good thing (for me). Help define some boundaries and help maintability. >> Grouping all Java classes by technical aspect at the project root : all >> services in one package, all models in one package can be tedious. >> >> On the front, if I correctly understood this thread : >> - a unique Msg / Model inside Main.elm can be a good starting point and >> easy to refactor later. >> - separating the view per feature (only view functions) : advice taken >> from Dave >> - break Model / Msg when too big (definition of "too big" is perhaps not >> easy, or someone can give some advices to detect "a too big Msg"). At this >> point, break Msg / Model / Update by feature. It is not all or nothing, >> just extract at first one feature and put them inside a file. Then the Main >> module wraps the feature (using map inside the Update). >> >> Can we imagine starting a community guideline somewhere ? adding examples >> later. >> Really easy for me to say that. >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Elm Discuss" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
