>
> 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. 


This is exactly what we do throughout our entire SPA app. We use union 
types to manage overall state and protect our invariants, making it 
impossible for the app to be in an invalid state at any time. The union 
types may get a little deep at times, but the payoff is more than worth it. 

On Sunday, October 23, 2016 at 3:29:23 PM UTC-4, 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.

Reply via email to