So I'm making a little toy ember app that will present a user with some improv prompts to create a comic strip out of. After a certain amount of time, the user will be able to upload their completed comic.
I've got the whole thing working up to the point of preseting the form to the user to upload their completed comic.
So far, everything is one route, controller and model (prompts). At the end though, they really should be working with a comic record. At the present, everything is in the same template, and I put the upload form into a view:
App.UploadComicView = Ember.View.extend
templateName: "upload_comic"
tagName: "form"
classes: ['form-horizontal']
submit: ->
#get('controller').uploadComic(#get('comicTitle'))
false
For the following model:
App.Comic = DS.Model.extend
title: DS.attr('string')
And I attempted to do the following in the prompts_controller:
uploadComic: (title) ->
App.Comic.createRecord(title: title)
#get('store').commit()
However, that attempts to sent a update action to the prompts controller on the backend, not a create request to the comics controller.
So it seems like I really should have a separate ember controller/template/model/route for comics, but I'm not sure how to get from the prompts controller at the end of the challenge to the comics controller in order to create a new comic object in the database. To make matters worse, I also really need to send the selected prompts from the current prompts controller to the new context.
What would be the best way to proceed?
When you do a App.Comic.createRecord it will do a POST to /comics with the request body {title: 'your title'}. This is regardless of which controller/location you do it from. Are you saying that it goes elsewhere? Please post a jsbin if this is the case.
Regarding the need to communicate with/access other controllers, you can use the needs declaration inside the other controller.
needs: 'comics'
comicsBinding: 'controllers.comics'
You can now access the comics controller via this.get('comics') inside it.
Related
I'm having a part of my applications split away from the main template in a sepparate handlebars template using {{render "header"}} to render that at the right place.
This sepparate template also has its own controller to display some data from the model (App.Notification).
What I want to do is display a limited amount of notifications and the number of new notifications in total.
Ember data loads 10 entries from the server when the controller's notifications property is called in an each loop but as soon as I try to limit the amount of shown notifications via splice, it won't return any data.
Basically, I'm having trouble handling model data if I can't set the controllers model in a route, I assume that's why the normal syntax with slice isn't working in this case.
I already searched Stackoverflow and the Ember docs but only found examples with normal Route -> Controller setup but nothing on this particular topic, so the question is, how to correctly handle model data in this setup?
Header Controller:
App.HeaderController = Ember.Controller.extend
notificationNew: (->
#get('notifications').filterBy('seen', false).get('length')
).property('notifications')
notifications: (->
#store.find('notification').slice(0, 2)
).property('#each.notification')
Template:
{{#each notifications}}
...
{{/each}}
To set properties on a controller not affiliated directly with a route by naming convention refer to the following jsbin.
http://emberjs.jsbin.com/gugajaki/3/edit
App = Ember.Application.create();
notifications = [
{seen: false, message: "tornado siren!!"}
{seen: true, message: "Omg lol security breach"}
{seen: false, message: "BFF Rite?"}
{seen: false, message: "steve kane 4 prez?"}
]
App.HeaderController = Ember.Controller.extend
newNotifications: Ember.computed.filterBy("notifications", "seen", false)
App.ApplicationRoute = Ember.Route.extend
setupController: (controller, model) ->
headerController = this.controllerFor("header")
#this can be a remote fetch via find. will work the same
headerController.set("notifications", notifications)
There are several issues in your posted code will are addressed in the link but I will enumerate here for clarity:
You can use the length property directly in the template
Use the Ember.computed.filterBy to get very efficient array observations
Configure your singleton instance of the header controller by using the application route's "controllerFor" method
I don't understand the splice but I wouldn't do it anyway
Hope this helps.
Ive got little basic problem with ember.
Here is app: http://emberjs.jsbin.com/qivamuzu/5 (click test - working like a charm, because model is in memory - loaded in index page)
But when you try page #test directly http://emberjs.jsbin.com/qivamuzu/5#/test all the data disappear (and that's bad - does not fired index route and load model). I follow this question Why isn't my ember.js route model being called? but doesn't help me.
I need to use template with model in other templates - I use {{render index}} but I'm not sure what to use and how. Please help me I am stuck.
I'm a little unclear on exactly what you're trying to do.
If you're just trying to use the same model data with a different route (and template) then you can explicitly set the model data to be the same in the route definition:
App = Ember.Application.create();
App.Router.map(function() {
this.route('test');
});
var myModelData = ['red', 'yellow', 'blue'];
App.IndexRoute = Ember.Route.extend({
model : function(){
return myModelData;
}
});
App.TestRoute = Ember.Route.extend({
model : function(){
return myModelData;
}
});
Here's a working JSBin example:
http://emberjs.jsbin.com/qivamuzu/8/edit
EDIT: Additional Information That May Help
Okay, one more stab at it =) When you navigate directly to the test page there is no data because the TestRoute is using the model data from the IndexRoute which hasn't been loaded yet. What you can do is force the creation of the IndexController and model by initializing it from the ApplicationRoute which will always be invoked when you first go to any route in your application.
First you have to generate the controller since it doesn't exist yet.
this.generateController('index');
Then you can get the controller and set its model data:
this.controllerFor('index').set('model', ['red','green','blue']);
Here's a working fiddle and I actually tested it this time to make sure it works when you go straight to #/test. I removed the extra routes and things that aren't actually needed from my previous example.
http://emberjs.jsbin.com/qivamuzu/11#/test
In every example I see, we always use data like if we knew what was the next ID. I'm building a web application that multiple users will be using at the same time. When a user click on the button "Create a category", I create a new record, send it to my API that saves it in the DB. Unfortunately Ember has no idea of my new Category ID. Let's say he made a typo. He click on "Modify". The app has no idea of the ID and therefor, cannot complete the route :product_id/edit.
I see two solution :
One thing I tried, that would potentially fix my problem is returning the ID in a the header. So I would send my data, return Status 201 (Created) if everything went well, then get the content of the Header and assign the created ID. Looks good on paper, but I have no idea how to get the content of my header with Ember.
App.CategoriesAddRoute = Ember.Route.extend({
setupController: function(controller) {
controller.newRecord();
},
actions: {
save: function() {
controller = this.controllerFor("category");
// Here I'd like to use something like .then( getHeaderContent('id') )
// and assign that value to the category
controller.get('content').save()
this.transitionTo('categories.index');
}
},
});
Reload my categories data with a new query. I would like to avoid that but if I have no other choice I'll go for this.
It's standard practice on save of a new model (POST) to return the model back from the server with the new id. After the server returns the model Ember Data will update the model so the model client side should have the id.
I'm using the new Ember-data 1.0.0 beta3 and have this issue (which I did not have with 13 revision!)
Giving two models with hasMany relationship
App.Post = Ember.Model.extend
title: DS.attr('string')
images: DS.hasMany('image', async:true)
App.Image = Ember.Model.extend
title: DS.attr('string')
I have a lot of images in the application and not necessary that one belongs to post.
Then, I'm trying to push some images to Post from the controller (does not matter from where is this context)
assignImage: (image_id) ->
post = #get('controllers.post.content')
#store.find('image', image_id).then (image) =>
topic.get('images').addObject(image)
post.transitionTo('updated.uncommitted');
So far so good, I got a "Cancel" button active because, I have manually sent a Post to "isDirty" state, but the issue is, when I'm doing rollback()
discardChanges: (post) ->
if(post.get('isDirty'))
post.rollback()
I'm not getting the state before I have added the image, I'm mean: it is working for "title" but not for image_ids
Does any one know if it's expecting behaviour or/and how to fix it?
Again: with rev13 was everything fine :(
As the good guy mentioned here, and after checking the source
http://discuss.emberjs.com/t/ember-data-1-0-beta-3-parentmodel-rollback-does-not-rolling-back-children-state/3351/3
It' s a current Ember-data behaviour now, I fixed it for now in old-fashioned way
Save a separate instance of the children, initChildren
Revert to it when hitting 'Discard changes'
I have a fantasy sports app with Player and Team models. I'm trying to output a query on the Players model/fixture as a model iterated by a template in a named outlet. I think my problem is with the 'availableTeams' controller/route/model/route.
I'm trying to do a find on my Player model for players that don't have a team.
App.AvailablePlayersController = Ember.ArrayController.extend({
availPlayers: function() {
return App.Player.find({league: ''});
// return App.Player.find({league: 'mlb'}); // Doesn't work either
},
});
The template is rendering because the static text shows up, but the Chrome emberjs debugger shows the model of availablePlayers as having no value. I've searched SO, the EmberJS.com getting started guide and countless JSFiddles, but nothings working. I don't know if my approach is wrong, or if I'm missing something simple. Any help is appreciated.
Full JSFiddle is here: http://jsfiddle.net/sandalsoft/77P8z/
PS - The app is a multiple-sport fantasy league where teams are the players, so don't let the team names in the Player fixture throw you.
EDIT: Updated the fiddle which now runs: http://jsfiddle.net/77P8z/
When you use renderTemplate your controller does not get a model from the route, since there is no route. The finder you used is returning a promise, but this stuff belongs in the route. It's a Catch-22, so you have to manually set the content or model on the controller.
I typically do this just before the custom render. You could do it it elsewhere, the key is to set the content manually. Here's the modified renderTemplate of ApplicationRoute,
var availController = this.controllerFor('availablePlayers');
App.Player.find({league: 'epl'}).then(function(result) {
availController.set('model', result);
});
// render into outlet
The updated jsfiddle.
I noticed you are using rc.3. Try switching to rc.6 if possible, you will need the async router, and the bug fixes in it eventually.