I try to get my head around elm-parts. 
My goal is to have 3 levels of nested components:   A -> B -> Counter

I base my attempts 
on https://github.com/debois/elm-parts/tree/master/examples
I have added the following function to Counter: 

render1 : Parts.Get Model c -> Parts.Set Model c -> (Parts.Msg c -> m) -> c 
-> Html m
render1 g s = 
  Parts.create1 view update g s 

and defined a B component to have :

type alias Model =
  { counterA : Counter.Model,
    counterB : Counter.Model 
  }

type Msg
  = Reset
  | CounterMsg (Parts.Msg Model)

view : Model -> Html Msg
view model =
  div
    []
    [ Counter.render1 .counterA (\m c -> {c | counterA = m}) CounterMsg 
model
    , Counter.render1 .counterB (\m c -> {c | counterB = m}) CounterMsg 
model
    --, Counter.render CounterMsg [1] model
    , button [ onClick Reset ] [ text "RESET" ]
    ]


Question: How do I define an A component to again have pair of B components 
and its model to be:

type alias Model =
  { bA : B.Model,
    bB : B.Model 
  }


Such example would actually be very useful to compose component based apps 
(and libs)

Many thanks,
Daniel



On Thursday, 19 May 2016 10:33:51 UTC+1, debois wrote:
>
> They both have been already:
>
> http://package.elm-lang.org/packages/debois/elm-mdl/4.0.0/
> http://package.elm-lang.org/packages/debois/elm-parts/2.0.0/
>
>
> On Thursday, May 19, 2016 at 11:27:46 AM UTC+2, Daniel Kwiecinski wrote:
>>
>> Any plans to update elm-mdl and elm-parts to 0.17?
>>
>> On Thursday, 19 May 2016 07:32:23 UTC+1, debois wrote:
>>>
>>> As I understand it, you want to write a function which takes a list of 
>>> TEA components, then wires up and renders those. As Peter pointed out, this 
>>> can be done when your "components" are really just view functions. If they 
>>> are actual TEA components, each with (view, update, Model, Message, 
>>> Subscription), there's a problem in that you'll need, someplace, a type 
>>> that can host "Model" for any such component. I don't think Elm has such a 
>>> type. 
>>>
>>> I wrote a library for treating TEA-components uniformly (
>>> https://github.com/debois/elm-parts); elm-mdl uses that. It gets most 
>>> of the way, but in the end, to use it, you have to make a record that 
>>> contains every type of Model you are treating. Elm-mdl does it like so: 
>>> https://github.com/debois/elm-mdl/blob/master/src/Material.elm#L178-L190
>>> .
>>>
>>> I wrote a blog post about how this is achieved: 
>>> https://medium.com/@debois/elm-components-3d9c00c6c612#.x5mtskkmg. 
>>> (It's phrased in 0.16 terms, though.)
>>>
>>>  
>>>
>>> On Wednesday, May 18, 2016 at 6:38:45 PM UTC+2, Daniel Kwiecinski wrote:
>>>>
>>>> Hi Peter,
>>>>
>>>>    Just skimmed on the gist, but can already tell this is great help. 
>>>> Many thanks for your work.
>>>>
>>>> Cheers,
>>>> Dan
>>>>
>>>> On Wednesday, 18 May 2016 15:20:38 UTC+1, Peter Damoc wrote:
>>>>>
>>>>> This gist (previously posted)
>>>>> https://gist.github.com/pdamoc/aef6306a9001de109aeece37e5627d06
>>>>> is a kind of minimalist example. It shows how to join together 2 
>>>>> different widgets (RandomGif and Counter). 
>>>>> The process for extending the list with new widgets is mechanical, 
>>>>> just add options to all the relevant types. 
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Wed, May 18, 2016 at 4:59 PM, Daniel Kwiecinski <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Sounds very promising. Could you please provide minimalist example?   
>>>>>>
>>>>>> On Wednesday, 18 May 2016 13:47:16 UTC+1, Peter Damoc wrote:
>>>>>>>
>>>>>>> You just use regular Elm Architecture and compose the model of the 
>>>>>>> autocomplete into the proper place, same with update and view. 
>>>>>>>
>>>>>>> To speak in React terms, what you had above are components that have 
>>>>>>> only props. These can be implemented with simple functions in Elm. 
>>>>>>>
>>>>>>> If a component needs state and rest calls, it needs to follow the 
>>>>>>> Elm Architecture. Please note that the component can be fully 
>>>>>>> encapsulated 
>>>>>>> in a module. The kind of boilerplate needed for state management is 
>>>>>>> very 
>>>>>>> small and very predictable. You can even extract it into some kind of 
>>>>>>> Widget abstraction and have all the Widgets be updated by a single line 
>>>>>>> of 
>>>>>>> code. :) 
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Wed, May 18, 2016 at 3:16 PM, Daniel Kwiecinski <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> This is fine. Big thanks for your effort.
>>>>>>>> But, how about instead of components being simple functions we have 
>>>>>>>> components as {init, update, view, subscription} so they encapsulate 
>>>>>>>> their 
>>>>>>>> logic. 
>>>>>>>> Think in having a component similar to google places autocomplete. 
>>>>>>>> From it's parent we still want to pass a configuration to it and react 
>>>>>>>> to 
>>>>>>>> the commands coming from the autocomplete (such as place changed) but 
>>>>>>>> we do 
>>>>>>>> not want or need to interfere with the autocomplete component internal 
>>>>>>>> state, rest calls etc?
>>>>>>>>
>>>>>>>> On Wednesday, 18 May 2016 13:08:21 UTC+1, Peter Damoc wrote:
>>>>>>>>>
>>>>>>>>> Oh, that's much easier:
>>>>>>>>>
>>>>>>>>> import Html exposing (..) 
>>>>>>>>> import Html.Attributes exposing (class) 
>>>>>>>>>
>>>>>>>>> helloComponent name = 
>>>>>>>>>   p [] [text ("Hello, " ++ name ++ "!")]
>>>>>>>>>   
>>>>>>>>> sayHello = 
>>>>>>>>>   helloComponent "world" 
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> listHello names = 
>>>>>>>>>   div [] (List.map helloComponent names) 
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> -- GENERIC WRAPPING COMPONENT
>>>>>>>>>
>>>>>>>>> wrapComponents components = 
>>>>>>>>>   div [class "components-wrapped-in-pages-so-we-can-swipe-them"]
>>>>>>>>>   (List.map (\c -> div [class "page"] [c]) components)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> names = ["Jim", "Bill", "Joe"]
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> main = 
>>>>>>>>>   wrapComponents 
>>>>>>>>>     [ sayHello
>>>>>>>>>     , helloComponent "Sandra"
>>>>>>>>>     , listHello names
>>>>>>>>>     ]
>>>>>>>>>
>>>>>>>>> There is no Signal anymore in Elm and if you use The Elm 
>>>>>>>>> Architecture, all you get is regular values. 
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Wed, May 18, 2016 at 1:15 PM, Daniel Kwiecinski <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Here is a sketch of how it would look like in reagent 
>>>>>>>>>> (ClojureScript)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> ; -- SOME CONCRETE COMPONENTS
>>>>>>>>>>
>>>>>>>>>> ; a component taking a String as a model
>>>>>>>>>> (defn hello-component [name]
>>>>>>>>>>       [:p "Hello, " name "!"])
>>>>>>>>>>
>>>>>>>>>> ; a stateless component using another component
>>>>>>>>>> (defn say-hello []
>>>>>>>>>>       [hello-component "world"])
>>>>>>>>>>
>>>>>>>>>> ; a component taking a ratom (it's a signal in elm speak) as a model
>>>>>>>>>> (defn reactive-hello-component [name]
>>>>>>>>>>       [:p "Hello, " @name "!"])
>>>>>>>>>>
>>>>>>>>>> ; a component taking list of Strings as a model
>>>>>>>>>> (defn list-hellos [names]
>>>>>>>>>>       (for [n names]
>>>>>>>>>>            [hello-component (str "hello " n)]))
>>>>>>>>>>
>>>>>>>>>> ; -- GENERIC WRAPPING COMPONENT
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> ; a wrapping components. take list of components as a parameter and 
>>>>>>>>>> wraps them in pages
>>>>>>>>>> (defn wrap-components [components]
>>>>>>>>>>       (fn []
>>>>>>>>>>           [:div {:class 
>>>>>>>>>> "components-wrapped-in-pages-so-we-can-swipe-them"}
>>>>>>>>>>            (for [c components]
>>>>>>>>>>                 [:div {:class "page"} c])]))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> ; -- MAIN VIEW GLUING ALL TOGETHER
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> (defn main-view []
>>>>>>>>>>       (let [reactive-name (ratom "initial-name")
>>>>>>>>>>             input-state (ratom "")]
>>>>>>>>>>            [:div {:class "some-boilerplate"}
>>>>>>>>>>
>>>>>>>>>>             ; the two lines below are not following re-frame 
>>>>>>>>>> pattern. There are there just to express I have the state which 
>>>>>>>>>> changes.  
>>>>>>>>>>             [:input {:onchange (fn [value] (!reset input-state 
>>>>>>>>>> value))}] ; react to inout changes and pass the value to model (in 
>>>>>>>>>> re-frame instead of directly updating the model we would send a 
>>>>>>>>>> signal (as in elm) and have subscription react to the signal but for 
>>>>>>>>>> simplicity I ommit the patern)
>>>>>>>>>>             [:button {:onclick #(!reset reactive-name 
>>>>>>>>>> @input-state)}] ; copy the states on button click
>>>>>>>>>>
>>>>>>>>>>             [:span {:class 
>>>>>>>>>> "here-come-generic-swipe-able-pages-wrapping-any-components"}
>>>>>>>>>>
>>>>>>>>>>              ; here is the usage of the wrapping container
>>>>>>>>>>              (wrap-components [
>>>>>>>>>>                                say-hello ; stateless component
>>>>>>>>>>                                #(hello-component "some-fancy-name") 
>>>>>>>>>> ; #(...) is lambda in clojure, here we close over some static state
>>>>>>>>>>                                #(reactive-hello-component 
>>>>>>>>>> reactive-name) ; #(...) here we close over some reactive state, so 
>>>>>>>>>> the component re-renders when the model (state) changes
>>>>>>>>>>                                #(list-hellos ["a" "b" "c"]) ; 
>>>>>>>>>> component taking list as a state (model)
>>>>>>>>>>                                ])]]))
>>>>>>>>>>
>>>>>>>>>> ; -- MOUNT VIEW TO DOM
>>>>>>>>>>
>>>>>>>>>> ; bind the main-view to DOM and start observing deltas to render if 
>>>>>>>>>> needed
>>>>>>>>>> (defn ^:export run []
>>>>>>>>>>       (r/render [main-view] (js/document.body)))
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Wednesday, 18 May 2016 08:42:45 UTC+1, Peter Damoc wrote:
>>>>>>>>>>>
>>>>>>>>>>> Can you mock some code that would show how would you like to use 
>>>>>>>>>>> this? 
>>>>>>>>>>> Imagine that it is already implemented in some library and write 
>>>>>>>>>>> against that imaginary library. 
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Tue, May 17, 2016 at 5:36 PM, Daniel Kwiecinski <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> The problem is that the generic container component (Let's call 
>>>>>>>>>>>> it C) do not know about it potential children (let's call them X, 
>>>>>>>>>>>> Y, Z) . 
>>>>>>>>>>>> There is top level component (Let's call it T) which has a 
>>>>>>>>>>>> knowledge about 
>>>>>>>>>>>> all of them (it is the app). The C is in self contained package, 
>>>>>>>>>>>> you can 
>>>>>>>>>>>> consider it to implement material design list view. How Can I 
>>>>>>>>>>>> implement C 
>>>>>>>>>>>> so T can use T with X, Y, Z ?
>>>>>>>>>>>>
>>>>>>>>>>>> On Tuesday, 17 May 2016 15:09:36 UTC+1, Peter Damoc wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> Hi Daniel, 
>>>>>>>>>>>>>
>>>>>>>>>>>>> If you have a limited number of components you can unify them 
>>>>>>>>>>>>> into one kind of a component. 
>>>>>>>>>>>>>
>>>>>>>>>>>>> Here is a self contained example that unifies Counter and 
>>>>>>>>>>>>> RandomGif and then uses them in a single list. 
>>>>>>>>>>>>> https://gist.github.com/pdamoc/aef6306a9001de109aeece37e5627d06
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Tue, May 17, 2016 at 3:47 PM, Daniel Kwiecinski <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> So let me expand my scenario a little bit. Lets assume that 
>>>>>>>>>>>>>> the CounterList component is very feature heavy. It makes lots 
>>>>>>>>>>>>>> of work to 
>>>>>>>>>>>>>> layout its children, manages drag to sort or whatever fancy 
>>>>>>>>>>>>>> stuff you can 
>>>>>>>>>>>>>> imagine. Now in my app I have many instances of usage of 
>>>>>>>>>>>>>> CounterList and I 
>>>>>>>>>>>>>> want to apply the complex behaviour not only to counters but 
>>>>>>>>>>>>>> also to gif 
>>>>>>>>>>>>>> and to mixed counters with gifs and many many other possible 
>>>>>>>>>>>>>> configurations 
>>>>>>>>>>>>>> (think in hundreds). I don't really want to implement dedicated 
>>>>>>>>>>>>>> CounterList, GifList, 2GifsWith3CountersList and other few 
>>>>>>>>>>>>>> hundreds 
>>>>>>>>>>>>>> SomethingBlaBlaList.
>>>>>>>>>>>>>> Is it possible in elm at all? If yes how so?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> P.S. It is not imaginary question. I try to port existing 
>>>>>>>>>>>>>> application implemented in Re-Frame (ClojureScript framework) in 
>>>>>>>>>>>>>> which this 
>>>>>>>>>>>>>> scenario is trivial.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Tuesday, 17 May 2016 13:33:27 UTC+1, Wil C wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Daniel,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I think normally, you don't. I think the constraint here is 
>>>>>>>>>>>>>>> that you need to explicitly set the types of each of the 
>>>>>>>>>>>>>>> sub-components for 
>>>>>>>>>>>>>>> every component that you make for a page. In the example that 
>>>>>>>>>>>>>>> you give, 
>>>>>>>>>>>>>>> you'd actually need to create 4 types of components: TopLevel, 
>>>>>>>>>>>>>>> Counter, 
>>>>>>>>>>>>>>> CounterList, and Gif. 
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> TopLevel component would include CounterList and Gif. And 
>>>>>>>>>>>>>>> then CounterList would contain Counters. It is CounterList's 
>>>>>>>>>>>>>>> job to 
>>>>>>>>>>>>>>> dynamically keep track of the number of Counters. That way, you 
>>>>>>>>>>>>>>> don't need 
>>>>>>>>>>>>>>> a generic component to contain an unknown number of things with 
>>>>>>>>>>>>>>> unknown 
>>>>>>>>>>>>>>> types. And then if those components need to talk to each other 
>>>>>>>>>>>>>>> (Like once 
>>>>>>>>>>>>>>> you add 5 or more counters, you see a funny cat gif), I believe 
>>>>>>>>>>>>>>> you can 
>>>>>>>>>>>>>>> send messages through Cmds (in 0.17) or Effects (in <0.17). 
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> With the hierarchical thinking of laying out components, I 
>>>>>>>>>>>>>>> found that Thinking in React 
>>>>>>>>>>>>>>> <https://facebook.github.io/react/docs/thinking-in-react.html> 
>>>>>>>>>>>>>>> helps. 
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> If you find that you really need the flexibility of having 
>>>>>>>>>>>>>>> different components in a container, it's doable. But it comes 
>>>>>>>>>>>>>>> at a cost. 
>>>>>>>>>>>>>>> Generally, if you're making a web app of some sort, it's not 
>>>>>>>>>>>>>>> needed. I 
>>>>>>>>>>>>>>> cover entity component systems recently in another thread, and 
>>>>>>>>>>>>>>> it's for 
>>>>>>>>>>>>>>> games.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> https://groups.google.com/forum/#!topic/elm-discuss/c9MhBzVPbr8
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Wil
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Tuesday, May 17, 2016 at 5:13:56 AM UTC-7, Daniel 
>>>>>>>>>>>>>>> Kwiecinski wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Elmers,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Here is my scenario. Say I have Main.elm which defines main 
>>>>>>>>>>>>>>>> view form my application. I also have bunch of other 
>>>>>>>>>>>>>>>> components (with their 
>>>>>>>>>>>>>>>> corresponding model  and message types) say Counter and Gif. 
>>>>>>>>>>>>>>>> (
>>>>>>>>>>>>>>>> https://github.com/evancz/elm-architecture-tutorial/blob/master/nesting/Gif.elm
>>>>>>>>>>>>>>>> )
>>>>>>>>>>>>>>>> (
>>>>>>>>>>>>>>>> https://github.com/evancz/elm-architecture-tutorial/blob/master/nesting/Counter.elm
>>>>>>>>>>>>>>>> )
>>>>>>>>>>>>>>>> Now I'd like to create new generic component which as a 
>>>>>>>>>>>>>>>> parameter (initial value of its model?) takes list of any type 
>>>>>>>>>>>>>>>> of component 
>>>>>>>>>>>>>>>> (say two counters, then one gif and another three counters) 
>>>>>>>>>>>>>>>> and wraps them 
>>>>>>>>>>>>>>>> into some decorating html.
>>>>>>>>>>>>>>>> The scenario serves as a illustration of the question, how 
>>>>>>>>>>>>>>>> do I implement components which can wrap lists of arbitrary 
>>>>>>>>>>>>>>>> component types.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> --
>>>>>>>>>>>>>>>> Regards,
>>>>>>>>>>>>>>>> Daniel
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> -- 
>>>>>>>>>>>>>> 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.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> -- 
>>>>>>>>>>>>> There is NO FATE, we are the creators.
>>>>>>>>>>>>> blog: http://damoc.ro/
>>>>>>>>>>>>>
>>>>>>>>>>>> -- 
>>>>>>>>>>>> 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.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> -- 
>>>>>>>>>>> There is NO FATE, we are the creators.
>>>>>>>>>>> blog: http://damoc.ro/
>>>>>>>>>>>
>>>>>>>>>> -- 
>>>>>>>>>> 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.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> -- 
>>>>>>>>> There is NO FATE, we are the creators.
>>>>>>>>> blog: http://damoc.ro/
>>>>>>>>>
>>>>>>>> -- 
>>>>>>>> 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.
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> -- 
>>>>>>> There is NO FATE, we are the creators.
>>>>>>> blog: http://damoc.ro/
>>>>>>>
>>>>>> -- 
>>>>>> 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.
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> -- 
>>>>> There is NO FATE, we are the creators.
>>>>> blog: http://damoc.ro/
>>>>>
>>>>

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