Ember: How Can I define an Item Controller in my Array Controller? - ember.js

I've created a table in my app by iterating through a list of rows like this:
{{#each visible_page itemController='ScheduledReport'}}
.....
{{/each}}
Now, I'm trying to abstract this table so that I can use it for more than just these reports. So, I want to define the itemController in the ArrayController rather than inlining it in the template:
App.ReportsScheduledController = App.TableController.extend(
{
itemController : 'scheduledReport'
However, defining the itemController in the ReportsScheduledController -- which inherits from Ember.ArrayController -- doesn't render each row in the table.
Any idea what I'm doing wrong in this setup?
Thanks!

You need to iterate over the controller in the template for that to work. Iterating over properties in the controller doesn't apply the wrapping of the item controller.

Related

How to get the outer parent controller from inside an ember component?

Currently I'm passing a custom keyword into the component like so (as I loop over each model in my array controller)
{{#each thing in controller}}
{{my-thing foo=controller}}
{{/each}}
Then inside my component I can add a custom attributeBindings and bind to "foo" but I'd like to think I can get access to the parent controller (from inside the component itself)
How else can I get this from inside the component in ember 1.8+ ?
Check out targetObject:
If the component is currently inserted into the DOM of a parent view, this property will point to the controller of the parent view.
In the Component, you can use this.get('targetObject'); to get the Controller of the parent view.

Ember: Idiom for ArrayController to loop through same-named ObjectController

I have the following pattern recurring throughout my app, and I was wondering if there is a way to clean this up:
Array Controller:
App.ThingsController = Ember.ArrayController.extend()
Template for Array Controller (using Emblem)
each thing in controller
= render 'thing' thing
Object Controller:
App.ThingController = Ember.ObjectController.extend()
I don't like having that intermediary template that has only those two lines.
I looked into itemController as a potential solution but that doesn't seem to do what I want.
Instead of rendering inside your each loop you could just include the code, and then use itemController. This would consolidate your templates into one, but still allow you to use the ObjectController.
{{each thing in controller itemController="thing"}}
{{thing.name}}.id = {{thing.id}}
{{/each}}

itemController for hasMany

I've been struggling with the following question for a while: How do I assign an itemController to child elements in a hasMany relationship?
My use case is the following: I have an Ember.View (ProjectView) in which I manipulate areas on the map using the Google Maps API. I have a model for the Area and the Project model "hasMany" areas.
I do not have any save buttons or the like in my app, but rather sync changes to the backend when a change occurs (using a debounce function). In order to avoid nasty inFlight errors, I am using a modified version of the Ember.AutoSaving plugin https://github.com/gaslight/ember-autosaving, which buffers my changes and synchronizes them with the model when it's ready. However, in order to use this, I need to apply an itemController using this Mixin to every Area in my hasMany relation. How do I go about this?
The Handlebars {{each}} helper has an itemController option. When this option is specified each object will be wrapped by a controller instance. So something like this should work:
//from your project template
{{#each area in areas itemController="area"}}
<pre>
area is an AreaController: {{area}}
area.content is a reference to the model: {{area.content}}
{{/each}}
See the [handlebars {{each}} API docs] (http://emberjs.com/api/classes/Ember.Handlebars.helpers.html#method_each) for more details
EDIT: Option 2
As an alternative to using the {{each}} helper, use an ArrayController to represent the collection and set it's itemController property. For example:
App.AreasController = Ember.ArrayController.extend({
itemController: 'area'
});
App.AreaController = Ember.ObjectController.extend( Ember.AutoSaving, {
bufferedFields: ['title', 'body'],
instaSaveFields: ['postedAt', 'category'],
titleLength: function() {
return this.get('title').length;
}.property('title')
});
// In your project route:
setupController: function(controller, model) {
this.controllerFor('areas').set('content', model.areas);
}
Now the areas controller will wrap each item in an AreaController proxy.
See Ember ArrayController API docs

EmberJS - change how an object property is displayed (not tied to route's controller)

Within my Ember app, I have an object model, called Item, with a property 'price', which holds a float value, such as 20.5. When I use the property in a template {{price}}, I would like for it to be formatted to look like so: $20.50.
This object is not the model that is tied to the controller at the route, but rather an element in an Ember Array, called items, which is a property of the model at the route. So I have something like this in my template:
{{#each item in items}}
{{item.price}}
{{/each}}
The problem seems pretty simple, but I can't really find a solution. The idea is that I do not want to change the name of the property to get it to look the way I want, since I could make a computed property that formats the price property, but then I would have to use a new name in the templates.
What you could do is write your own custom handlebars helper.
For your use case it would look something like this:
Ember.Handlebars.registerBoundHelper('formatNumber', function(value) {
return "$" + value.toFixed(2);
});
And then use it in your templates this way:
{{#each item in items}}
{{formatNumber item.price}}
{{/each}}
Please see here for a working jsbin.
Hope it helps.

ember.js #each order by property

I have an array of Ember.Objects which is displayed by Handlebars {{#each}} helper which I want to be sorted by an property of those objects everytime the array changes.
So something like this:
var arr = [
Ember.Objects.create({
position:0,
label:"foo"
}),
Ember.Objects.create({
position:1,
label:"bar"
}),
];
And the handlebar
{{#each arr}}
<div class="label">{{label}}</div>
{{/each}}
So if I update the positions and the bar object becomes first, I want the view to be updated. Can I depend the {{#each}} Helper on an property?
You have to use an ArrayController proxy on your data, and set the sortProperties attribute. Then, use the controller as the each data source.
Sample # http://jsfiddle.net/MikeAski/Epjqp/
Using the controller as the data source provides an arranged content. Take care not to use directly the controller's content, as it is the raw source data...