I made the “mistake” of not learning ember inside out before tackling a fairly complex project, but on the other had needed to make some progress.
Let’s say I got a “parent” and a parent have zero to many “children”
So what I basically have is a “parent” model/route/template in which I have 2 components.
One for editing the parent, and one with a dropdown (parent’s children) that will load a different child in the second component when selected (the dropdown is in the “child” component)
I ended up with the component using the store (injected as a service) and right now running into all kinds of issues and not sure I took the right approach (so it’s just my lack of knowledge troubling me) or this was a bad idea to start with.
Thoughts?
In general its better to retrieve / keep your data in router.model(), and pass the data (down) to a component (via template attributes).
When the component needs to change the model, it sends an action (back up) to the router which will update the model, and this will in turn update the components (since they use the model).
hth
4 Likes
After I struggled half a day with same problems as the thread creator, I came also to the conclusion, that I need to handle the actions somewhere in the more “upper levels”, meaning routes or controllers.
But … I never read about in the official guides, that the handling of actions should happen in the applications Routes. But for sure, I’ve read, that the data-handling not should happen in the component. If it should not happen in the component, and we should forget controllers since v2.0, maybe the handling should really happen in the Route?
At the moment, I tried different ways:
- inject the
store
in the component and manipulate the model
-array (meaning creating a new record and push it to the model array)
- bubbling up the actions from the component to the controller and …
- injected a service in the controller where the
model
-array gets manipulated
- manipulated the
model
-array within an action of the controller
All of these methods did not trigger an update of the model
data gave to the component.
Actual structure:
App
> Controller A
> Route /x/i
>- SubController B of Controller A
>- - Component "1"
> Route /x/ii
>- SubController B of Controller A
>- - Component "1"
> Route /x/iii
>- SubController B of Controller A
>- - Component "1"
In all of the x
routes, I will do with different topics
:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
let params = this.store.peekAll('Parameter');
return params.filterBy('topic', 'cri');
}
});
I will then pass the model-array from the Controller
to the Component
:
{{#dt-leasing-params
title='CRI'
model=model
parameter-topic='cri'
parameter-sign="%"
--this is just for the syntax highlighter of discuss}}
{{!-- here is how I bubble the action up to the ctrl --}}
new-param=(action "new-param" "cri")
{{!-- and here is how I send the action to the service, that is injected in the parent controller --}}
createParam=(action "add-dt-param" "cri" target=add-dt-param) as |crtParam|
{{/dt-leasing-params}}
After writing this post, I’ve switched from peekAll
to findAll
, which will then keep the model in the component up to date.
Or dear. These fridays …
###Edit:
Due to the fact, that store.findAll()
seems to keep the model of the controller/component up to date, while store.peekAll()
and store.query()
will do that not, how can we ensure, that store.query() will keep the component up to date? Is this possible? Otherwise it seems, that I’m always willed to perform a store.findAll() on smaller components, that manipulate an model array.
Anyone has an answer to my last question?
peekAll and peekRecord won’t make a network request, they will only look at what is already in the store, that is how they work
The docs are pretty good on Ember Data so if you have the time then have a read, it’ll save you that time later I promise!
For sure, @ricky1981. I’ve read them. Several times.
But there is no note about that:
I have a route. I load all {model:parameter} in that route via this.store.findAll('parameter')
.
In that route exists a component which will use that model. If I create a Record in the store via the component and used findAll()
, all is fine and the model in the component got an update. But if I search for model data via peekAll()
or find('parameter', {topic: 'plasmacore-related'})
, the model in the component won’t get an update.
So my question will be like this: How can I fetch model-data with a query or filter, and the model also get an update, or keeps staying up to date – Like, when I do find()
or findAll()
?
Edit: Why I do that?
Because I use the component on different routes, which all load the parameter
model, but just with different properties. The parameter
s differ on their topic: topic1, topic2, topic3, ...
. And I just need one
specific topic on each parameters-route.
So it will be fine, if I could query the parameters via .query()
or .find(..., {topic: ...})
– but I need the component to stay up to date and show fresh unsaved records, the user created.