Hacker News new | comments | show | ask | jobs | submit login

I really like this architecture - it's clearly based on lessons learned from the same types of pains that I myself encountered w/ non-trivial jQuery, and the unidirectional data flow makes it a lot easier to reason about the code. It's very similar to what I'm doing with my own micro mvc framework Mithril ( http://lhorie.github.io/mithril ).

One thing that raise my eyebrows about this article though is how says that Flux eschews MVC, and then goes on to say that it has stores that are "somewhat similar to a model", and "the dispatcher exposes a method that allows a view to trigger a dispatch to the stores", which, as far as classic MVC goes, is the exact definition of a controller. What they call controller-view is, imho, just an implementation detail within the view layer: in classic MVC, views were responsible for subscribing to model observables, or, as the article puts it, it "listens for events that are broadcast by the stores that it depends on".

When talking about this architecture with the Mithril community, I find that referring back to the MVC pattern makes it even easier to reason about the flow of data: it's basically M -> V -> C -> M ...

It's unfortunate that the general understanding of the MVC pattern became misunderstood over the course of many frameworks. The whole point of design patterns should be that we could just name them for people to "get" it, rather than having to reinvent new ways of naming things and having everyone relearn the nomenclature.




Thanks for Mithril - we're experimenting with it vs react.js for production use. There's a lot of very smart design decisions there expressed in very terse code.

One thing that threw me off was startComputation() / endComputation(). It seems you have to be explicit about when properties are being updated for views to update. I worry this might be error-prone vs react.js - if you forget an endComputation(), or an exception occurs outside of a try/finally, your views will freeze forever, no?


That topic was brought up here:

https://github.com/lhorie/mithril.js/issues/68

Generally, you only need to manually call start/endComputation when integrating to 3rd party code that needs to update Mithril managed bindings.

In the latest release, I tweaked the rendering aggressiveness to allow redraws after exceptions in event handlers, and I updated the docs wrt `try/finally` blocks in integration scenarios.

One other thing people could do that I don't think should go in Mithril core is to call m.redraw inside window.onerror.

Of course, I'm open to other suggestions, if you have any.


At least in my application, views are always bound to either an `m.prop` or an immutable value. What if you tracked when an `m.prop` was updated and queued up a redraw automatically? Redraws would be rate-limited via requestAnimationFrames/setTimeouts as usual.

I imagine this could have a significant performance impact, but don't know the mithril internals well enough to say.

EDIT: Thinking about it, the virtual DOM must be re-constructed on every redraw since the props aren't tied to a view. This probably wouldn't work well then.


The topic of side-effect incurring getter-setters was also brought up a few times in various forms. I wrote about my thoughts on it here ( https://github.com/lhorie/mithril.js/issues/78 )

As far as redrawing impact goes, Mithril does rate-limiting, so even attempting to subvert m.prop to force it to spam redraws should still perform ok.


Thanks lhorie, it's great to hear that you've come to similar conclusions. I found that https://tech.dropbox.com/2014/04/building-carousel-part-i-ho... also described similar concepts, which is really encouraging.

To address your second comment: One distinction between the dispatcher and controllers in the MVC framework is that the dispatcher generally doesn't contain any business logic. It's essentially a hub for passing messages through: all sources of changes get funneled through the dispatcher, and the stores listen for those events, but the dispatcher doesn't actually modify or initiate the events. In my talk, I described it as the traffic controller of the system, which might be a more appropriate description.

As things get more complicated, the dispatcher may do more things at the framework level (Bill refers to the dispatcher handling dependencies between stores), but it stays separate from the application logic. In other words, we use the same dispatcher for multiple apps, so it plays a different role from the controller.

Hope that clarifies a bit, I'll see if we can make this distinction clearer in the documentation :)


Agreed. At some point, in a well designed app, you've got a data store, an I/O layer, and something that coordinates amongst the components. There are a million ways to decide where the "business logic" should live, whether application state and external data should be treated differently, or exactly how all the pieces are glued together. At the end of the day though, it's all pretty much the same paradigm.

It sounds to me like Flux goes with a model layer that handles all state (internal to the app and not), pushes most binding between pieces of the UI to the view layer, and uses a thin controller layer to mediate the other two layers and coordinate parts of the model layer with overlapping concerns.

I once had the epiphany that an entire web app is pretty much a whole bunch of nested or concatenated MVCs. I think the confusion arrives when people assume that there is one-and-only-one MVC and try to shoehorn all the parts of a new workflow into that rigid structure. I don't think that the proliferation of acronyms purporting to be something different helps with understanding.


To add to the acronym soup, what you described (nested MVC) is known as HMVC, and I agree that it's what most frameworks end up as, regardless of what they end up calling it. It works very well in my opinion, too, to the point where I'm currently working on a framework like that myself (as a learning exercise)




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: