Reputation: 14459
With Ember 2.2.0, I have a Route:
Dash.BacklogReportsRoute = Ember.Route.extend
model: ->
@store.queryRecord "report", newest: true
and a Component:
Dash.BacklogReportComponent = Ember.Component.extend
report: null
actions:
generate: ->
# Send the request.
$.ajax
type: "post",
url: "/reports/generate/#{new Date().getFullYear()}",
success: =>
# Update the model.
# TODO - how to reload the model in place? Or at least just refresh
# the Route so we don't have to reload the entire app.
window.location.reload()
which includes as part of the template:
<p>
Report was generated {{report.timestamp}}.
</p>
where timestamp
is a computed property on the Report model.
The Route's model is the most recent Report object, and via the POST
the generate
action causes the server to create a newer (thus more recent) Report. I want to update the timestamp of that [newer] Report.
My question is, in Ember 2, how can I cause the Route to refresh itself? I'm new to Ember so I'm not sure if it's possible to access the Route directly from within a Component (or if I can, if it's a good idea). I don't think just reloading the model would work, because after a successful POST
a different model (i.e. a record with a different id
) will be returned by @store.queryRecord "report", newest: true
than when the page loaded. The existing model will be the same after the POST
.
Alternatively, I'd be perfectly happy completely rerendering the Route (it's a very simple page) or transitioning to "this" page again, but I can't figure out how to do that.
For now I'm simply forcing an old-school page window.location.reload()
.
Looking at this another way, perhaps there's a more idiomatic way to approach this problem with Ember.
Should I be loading in all (or some) Reports with the Route, and forcing a refresh on that Collection after the POST
? I see Enumerable
has a .firstObject
property - is that a computed property (in other words, if my Routes model is a Collection of Reports and I push on to the front of that Collection, would that change propagate through .firstObject
references automatically?)
Upvotes: 0
Views: 2616
Reputation: 4214
If you need to manually reload the page, there really should be a better way. Ember as other similar frameworks are an SPA (single page application) and do their magic when updating only parts of the page very efficiently.
that being said, if you want to access the router
from the controller
/component
by sending an action to the router
and handling the changes in that action
.
see action bubbling https://guides.emberjs.com/v1.10.0/templates/actions/
Upvotes: 1
Reputation: 860
Well you can't actually access the route directly from the component. But that is no problem since you can use actions to achieve the same effect.
So first you need to send an action from your generate
action in your component:
Dash.BacklogReportComponent = Ember.Component.extend
report: null
actions:
generate: ->
# Send the request.
$.ajax
type: "post",
url: "/reports/generate/#{new Date().getFullYear()}",
success: =>
@sendAction('didGenerate')
Next you need to hook up the action in the template, so your controller/route gets notified when it is called:
{{backlog-report report=report didGenerate='didGenerateReport'}}
And now you can "catch" that action in your controller or route. We will do it in ther route so we can refresh it:
Dash.BacklogReportsRoute = Ember.Route.extend
actions:
didGenerateReport: ->
@refresh()
model: ->
@store.queryRecord "report", newest: true
Sorry if I made any mistakes with CoffeScript (didn't use it for quiet some time). Also there are other things you could improve. Generally I wouldn't put the ajax call in the component, I would put it in the controller/route if possible and call it with an action (I just have the experience that it's best to avoid putting ajax calls in a component, though there are usecases for it).
I would generally propose to read all of the ember guides if you didn't yet do so. They are pretty good and while you won't understand everything from the first read, you will at least more or less know what to look for, or what is possible.
Upvotes: 1