I just wrote a new version of example here
<https://gist.github.com/jinjor/cc9b74ccf0b24eb60dd2ed33e7b41d49>. This
container view can also handle the messages of its children that have
different kind of messages defined outside. I think this is more practical
than previous one. (I haven't tried it in my app yet, though)


2016-05-19 1:38 GMT+09:00 Daniel Kwiecinski <[email protected]>:

> 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 a topic in the
> Google Groups "Elm Discuss" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/elm-discuss/sJl8iB_3EXQ/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> 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