I want to use the information already received within a linked template. Nesting routes has created a whole heap of errors, and I'm a little lost on how to pass this data, but it seems like it must be possible?
This works, but strikes me as a poor hack. Ideally I'd only want one API round-trip...
App.Router.map ->
#resource 'photos'
#route 'photo', path: 'photo/:photo_id'
App.PhotosRoute = Ember.Route.extend
model: ->
Ember.$.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?tags=cake&tagmode=all&format=json&jsoncallback=?')
setupController: (controller,model) ->
controller.set 'photos', model.items.map (i) ->
i.id = model.items.indexOf(i)
App.PhotoRoute = Ember.Route.extend
model: (params) ->
jQuery.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?tags=cake&tagmode=all&format=json&jsoncallback=?').then (api) ->
api.items[params.photo_id]
App.PhotosController = Ember.ObjectController.extend
itemController: 'photo'
{{#linkTo 'photo' this }}<img {{bindAttr src="media.m"}} />{{/linkTo}}
You can use the modelFor(routeName) to get the model from some route. In your case probally you will fetch all data in PhotosRoute, and want to reuse it. You can use this in your PhotoRoute:
App.PhotoRoute = Ember.Route.extend
model: (params) ->
#modelFor('photos').items[params.photo_id]
So just one api call will be done.
Related
Sub route appending empty record to collection I've got a bit of a tricky problem and I'm hoping you peeps can help.
This works as expected BUT if I refresh the page with a location sub route the locations list gets an empty record appended to the end.
App.Router.map ->
this.resource 'home', { path: '/' }
this.resource 'locations', ->
this.resource 'location', { path: ':slug' }
this.resource 'services'
this.resource 'contact'
this.resource 'login'
App.LocationsRoute = Ember.Route.extend
model: ->
this.store.find 'location'
App.LocationRoute = Ember.Route.extend
serialize: (model, params)->
slug: model.get 'slug'
model: (params)->
this.store.find 'location', params.slug
Any help greatly appreciated
I've scouring for a bit, but can't find an answer to this. I've got an Ember route on a Rails app, and I would like one of the model records to be displayed by default when visiting the URL (right now, a user needs to click on a specific link to retrieve the data).
For example, when visiting /albums, I would like /albums/38 to be active and visible without forcing a redirect. Is that possible?
Thanks
App.Router.map ->
#resource 'albums', path: '/', ->
#resource 'album', path: '/:id'
App.AlbumsRoute = Ember.Route.extend
model: -> #store.find 'album'
Add an 'index' route for the 'albums' resource and redirect to the 'album' route with the first model. The index route will only be hit when you hit just the albums resource, and not when you hit deeper (aka not when you hit /albums/1).
App.AlbumsRoute = Ember.Route.extend
model: -> #store.find 'album'
App.AlbumsIndexRoute = Ember.Route.extend
model: ->
album = this.modelFor('albums').get 'firstObject' # This can be whatever...
this.transitionTo('album', album) if Ember.isEmpty(album) is no
The Ember.js application
# routes/application.js.coffee
########################################
App.ApplicationRoute = Ember.Route.extend
model: ->
#store.findAll('category').then (records) ->
{
categories: records
}
# routes/categories.js.coffee
########################################
App.CategoriesRoute = Ember.Route.extend
model: ->
#store.find 'category'
# routes/category.js.coffee
########################################
App.CategoryRoute = Ember.Route.extend
model: (params) ->
serialize: (model, params) ->
id: model.get('slug')
# templates/application.hbs
########################################
{{ partial 'categories' }}
<p>---</p>
{{ outlet }}
# templates/categories.hbs
########################################
<h1>Categories...</h1>
{{#each category in categories}}
{{#link-to 'category' category}}
{{category.title}}
{{/link-to}}
{{/each}}
# templates/category.hbs
########################################
<h2>{{title}}</h2>
<h3>{{description}}</h3>
# router.js.coffee
########################################
App.Router.map ->
#resource 'categories', path: 'categories'
#resource 'category', path: 'category/:slug'
# store.js.coffee
########################################
App.ApplicationAdapter = DS.ActiveModelAdapter.extend
namespace: 'api/v1'
What I am trying to accomplish
I am loading Category on the Application route so the data can be used to render the site-wide navigation via the categories partial.
Model is acquired successfully and stored, according to the Ember console. If it makes any difference, one-to-many data is being sideloaded, called Sections, which is also stored successfully.
The category partial is rendered as expected, with links to each section. Clicking on them yields the rendering of the title and description.
What is wrong
Refreshing the application on the route of say, /#/category/title-1, doesn't render the category view (both title and description). However, clicking on the links generated in the categories partial will render the view.
What I expect on page load is the rendering of the category view, without the need of clicking on the categories links. What am I doing wrong?
After playing around with the Application for too long, I figured out a solution to my problem.
When using the Ember console, I saw that the model for the Category view was referenced to [Object object] and not App.Category. I had to specify the store to search by the slug. Therefore, the code looks like this
# routes/category.js.coffee
########################################
App.CategoryRoute = Ember.Route.extend
model: (params) ->
serialize: (model, params) ->
id: model.get('slug')
#store.find('category', params.slug)
The view is now rendered on page load.
In my app, there are Templates and Documents. I want to be able to create a document from a template, i.e. the user will be able to go to the template show page, click a button, and be redirected to the new document page, with document text pre-filled from the template (I only need to have the text pre-filled, I don't care about the document knowing the template it's made from).
But how would I pass the text to the new document page?
I ended up doing the following:
App.Router.map ->
#resource 'documents', ->
#route 'new'
#route 'new_from_template', path: '/new/:template_id'
App.DocumentsNewFromTemplateRoute = Ember.Route.extend
model: (params) ->
model = App.Document.createRecord()
if params.template_id
App.Template.find(params.template_id).then (template) ->
model.set 'text', template.get('text')
model
setupController: (controller, model) ->
if model._reference.type == App.Template
model = #model(template_id: model.id)
#currentModel = model
#controllerFor('documentsNew').set 'model', model
renderTemplate: ->
#render 'documents/new'
And to link to new document form for template, I simply do
{{#linkTo 'documents.new_from_template' template}}Create a document{{/linkTo}}
You can define an action in the controller:
App.TemplateRoute = Em.Route.extend({
model: function() {
return Em.Object.create({
name: "A Template",
values: {title: "Templated Title"}
});
}
});
App.TemplateController = Em.ObjectController.extend({
goToNewDocument: function() {
var o = Em.Object.create(this.get('values'));
o.set('source', 'Template');
App.Router.router.transitionTo('newdoc', o);
}
});
App.NewdocRoute = Em.Route.extend({
model: function() {
return Em.Object.create({title: "Default Title", source: "Model hook"});
}
});
jsbin demo
I thought I had a fairly simple solution to find models with attributes other than ID, but I'm running into one problem.
Current setup:
Ember Router:
App.Router.map ->
#resource "posts", ->
#route "show", {path: ':slug'}
App.PostsShowRoute = Ember.Route.extend
serialize: (model, params) ->
object = {}
name = params[0]
object[name] = model.get('slug')
return object
model: (params) -> App.Post.find(params.slug)
Rails Controller:
class PostsController < ApplicationController
def show
#post = Post.find_by_slug(params[:id])
render json: #post
end
end
THE PROBLEM
If params.slug == "some-post", when post object is returned from the server, post.id == "some-post". This messes up all the associations.
This is probably because DS.Store is assuming that if I call find(something), something is the id. I would have expected that the response from the server would overwrite this assumption, but it doesn't.
Is there a better way to do this? My use case is extremely simple. All I need to do is serialize and deserialize a post object by the slug attribute.
I'm using Ember Data revision 11
The solution turned out to be findQuery. I was using this some time ago, but I didn't know how to make use of the promise.
model: (params) ->
#get('store').findQuery(App.Post, {slug: params.slug}).then (data) ->
return data.get('firstObject')
and on the rails side:
class PostsController < ApplicationController
def index
#posts = params[:slug] ? Post.where(slug: params[:slug]) : Post.homepage
render json: #posts
end