Honestly I think you’re making a mountain out of a mole hill. I never said I had a problem with components requesting data themselves, just that I debated whether it was a solid practice and came to the conclusion that for certain types of components it is.
Ember’s event flow is second to none, and it’s something I’m probably too well acquainted with. I’m honestly not sure how that’s even debatable, nor am I sure how you think it’s not simple.
A potential solution is to bind component options to route based query params so that the route can fetch new data on QP change and it can propagate down to the component.
This is a horrible idea, one which you found out. Query-params are for saving non-critical route state, you shouldn’t be using queryParams as a hack to manipulate component data.
Typically, you’ve got a defined controller(s) and a defined model(s). You can pass data from these to components directly, and if needed you can do so in a bound way. Let’s say this was my twitter widget.
I could pass statically
{{twitter-timeline username="runspired" keywords="ember components"}}
Or I could pass dynamically
{{input value=searchTerm action="addSearchTerm"}}
{{twitter-timeline username=model.username keywords=searchTerms}}
In the latter case, the “addSearchTerm” action bubbles to my controller where the matching function pushes the value onto the searchTerms
array, which updated my twitter component.
What’s awesome about ember’s actions-up data-down approach, is we could easily take this a step further. Let’s say this widget really doesn’t have anything to do with the route other than getting the current username. We could write our component like this.
{{input value=searchTerm action="addSearchTerm"}}
<ul class="tweets">
{{#each tweet in tweets}}
{{render "tweet" tweet}}
{{/each}}
</ul>
Now our keyword input is part of the component itself, and when it triggers addSearchTerm
our component can handle that action itself. No need for any other components / controllers / route to know about the need or logic of doing so.
You’ve been on quite a campaign against DDAU, and while I don’t think you don’t have a valid point of view to offer Ember, you’re suggesting a proven (and honestly amazing) design pattern is broken.
Ember is adopting fewer two way bindings after observing how coders use components and the performance / usability / maintainability costs therein, as well as looking at how well React has done with a unidirectional data flow.
That said, I’d like to discuss the below.
From another thread
I think the solution is to follow a unidirectional approach, not a DDAU approach. That is for state changes your components invoke semantic actions at the top level which then are delivered by a dispatcher to subscribed stores.
I think I now understand why you were trying to hack around with QueryParams. There are limited cases in which I would find this very useful, but I wouldn’t put it past the core team to add the ability to do something similar to this in 2.0.
Why wouldn’t I put it past them? Because with complex interfaces sometimes you do need a button to affect the state of multiple components, and since data only flows down, sometimes you’ll just want to target the closest route with an action that’s going to affect the state of multiple components, and having an “action” subscription program such as this is a lot safer than the pattern many use today of allowing components to alter data upwards.
That said, if that action is simply alerting to a change in data the route knows about, just letting the event bubble up, and the data change propagate down will have you covered.
A Parting Note on Events
I think you meant to say actions, not events. They are different, but intrinsically connected. That said, actions should go up the same way that events go up, for the same reason that DOM events bubble through the hierarchy Actions bubble through the View/Component hierarchy.
A simple example of this is the ember-mobiletouch library I’ve built as an addon, it bubbles taps and gestures through Ember’s event system, and let’s gestures trigger actions. By doing it this way, the component or view closest to the event each get’s it’s turn to handle the gesture.
Bubbling actions like events let’s us build layered, complex components that contain their own eco-systems without needing to wire up everything at the top level or expose more than a simple api. This is ideal for most of the “ambitious” apps I’ve worked on.