zaceno / hyperapp-modules

Turn a tree of hyperapp modules into state, actions and wired views
MIT License
0 stars 0 forks source link

Nested views #1

Open mshgh opened 6 years ago

mshgh commented 6 years ago

Hi There!

I am curious if there is any strong reason for allowing access to views only one level deep? Only to views of modules directly referenced, but not to views of inner modules of these modules. (if this makes any sense ;) e.g. according to your example assuming there is 'baz' module inside 'foo' module following element in the main view fails <views.foo.baz.ToolbarButton />

I have checked the implementation of your solution and I think this can be added by pretty small update Instead of return tree.view && tree.view(state, actions, subviews) you can use return Object.assign(tree.view && tree.view(state, actions, subviews), subviews) and code from the example above starts to work. As an idea, there should probably be some use of || {} and may be bit more.

How do you feel about this change? Can you see any disadvantages or problems?

Really like your approach to modules in hyperapp, BTW :-)

Mirek

zaceno commented 6 years ago

Hi @mshgh, and thanks!

Interesting suggestion!

Actually in my old library hyperapp-partial I had this feature (you could access the views of not only your own module, but all submodules, in a namespaced tree, just like the state and actions). But that library is from back before hyperapp even had slices, so it's not relevant anymore (although, with slices and state-mergeing being removed from hyperapp 2.0, it might see a resurrection 😉 )

Anyhow, there are two reasons I decided to omit that here. First, because I was trying to keep it dead simple. At first I never even intended to make a library, but the helper code in that blog post was just so useful, I kept copy-pasting it places so I made a module of it.

The second reason is more theoretical:

Basically, baz is an implementation-detail of foo. You would want to be able to completely refactor foo, and as long as you maintain the same interface, the rest of the app shouldn't break. But that's not true if the rest of the app depends on foo.baz.SomeView.

But what if I do consider .baz.* to be an interface of foo? That's unlikely. Because usually if foo depends on baz it's beacuse foo will do something with it. If foo is not going to wrap or manage baz.SomeView in any way, then you might as well include baz directly from the root, rather than make it a dependency of foo.

In the rare case where you do what to just pass SomeView along ontouched, you can easily do that in foo, exposing foo.BazSomeView

That's my thinking anyway :)

mshgh commented 6 years ago

Hi Zacharias,

I didn't consider manual exposing of sub-modules as this would be tedious job. However I can see your point about such need to be rather exception then rule. And it is true all I need to do is to publish view of sub-module. I can even preserve the namespacing to make it look exactly the way I wanted view: { baz: { SomeView: views.baz.SomeView } }

Thank you for your feedback it really help!

I still cannot help myself and I think this should have been built-in part of hyperapp :-)

Cheers, Mirek

zaceno commented 6 years ago

@mshgh Yes I feel the same way. And I think many do to.

But still others (@Jorgebucaran included) are more focused on emulating the Elm way. Which is indirectly why slices and auto-merging state are going away for 2.0.

The idea is (I believe) to leave it up to users to implement (or include libraries) whatever state-merging features and modularity-strategy they see fit.

So this lib will have to get quite a bit more complex to keep up to date with hyperapp 2.x. Sadly I can’t promise to maintain this going forward. We’ll just have to see...