ember.js #each order by property - ember.js

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...

Related

Bind to a value that will be fetched from an API

I have an endpoint that returns a list of artists (json data).
And an endpoint that returns a specific property given an id.
What I would like to do is to iterate through all the artists and display one or more properties in the template to the user but the property should only be fetched from the API if it is bound in the template.
In my ArtistsRoute, I set the model to be all those artists fetched by calling getJSON...
I want, somehow to be able to fetch a property for an artist and display it (through binding).
The Properties map could be stored in the ArtistController maybe.
I could not find a good example for this. Any help is appreciated!
Template example:
Name is on the artist object itself, but the Properties object has been created manually. So in the ArtistController it could be initialized to empty:
Properties = {}
And then it sets Propertes['ShortName'] = to the fetched value.
<ul>
{{#each}}
<li>
{{Name}}
{{Properties.ShortName}}
<img {{bind-attr src=Properties.MainImage}} />
</li>
{{/each}}
</ul>
Should I use a function instead as a property or a Handlebars helper? Like:
{{Property this 'ShortName'}}
where 'this' is the ArtistController and 'ShortName' is the property to fetched. The property id can be calculated through the ArtistController and propertyName.
function(tag, propertyName) {
Ember.$.getJSON('/Properties/' + tag.Id + '_' + propertyName).then(function(response) {
var propertyValueToBind = response.Value; // This is the value I want to display in the template.
});
}
Then the Property function has to know when to rerender the template (once the property has been fetched from the API).
Firstly you'll want to generally avoid properties that are uppercase. They are usually considered global properties, and not in scope.
Ember lazy loads computed properties by default, so adding that functionality to a computed property would be an excellent way to go.
someProperty: function(){
var promise = Ember.$.getJSON('/Properties/buildupurl');
return Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
promise: promise
});
}.property()
Then in your template someProperty would be accessed like this
{{someProperty.value}}
And would be asynchronously populated.
Example: http://emberjs.jsbin.com/OxIDiVU/769/edit

Ember: How Can I define an Item Controller in my Array Controller?

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.

In Ember.js updating the controller property will not update the view'

I am using the controller property as array initially the view will render once after updating the array the view is not getting updated.
Eg:
Handlebar:
{{#each records}}
{{name}}
{{/each}}
Controller:
App.recordsController = App.EventHandlerController.extend({
records: null,
actions:{
//stmt1
var array = ["test", "test2"];
this.set('records', array);
//stmt2
array.push("data");
this.set('records', array);
}
});
The view is not getting updated after statement 2 What is the reason for this?
This is failing because it is not valid JavaScript. The object passed to extend is a JavaScript object, which consists of keys and values. After records: null,, you have code that looks like it belongs in some function. You should have seen an error in your console describing this.

Pass array to linkTo helper

I want to create a component which needs to generate dynamics links. I tried passing the link data as an array, but this does not work.
var user1 = get("store").find("user", 1);
var data = {link: ["users.show", user1], title: "User1"};
{{#link-to data.link}}{{data.title}}{{/link-to}}
This should be equal to
{{#link-to "users.show" 1}}{{data.title}}{{/link-to}}
How to generate fully dynamic links from a variable?
You can specify an array as params argument into a link-to helper. Similar to nickiaconis' answer answer, but with just the default {{link-to}} helper:
{{#link-to params=data.link}}{{data.title}}{{/link-to}}
...will render something like:
User1
(tested with Ember 2.3.0)
Ember 1.13.x
The LinkComponent, which is what the link-to helper creates for you, is exposed as -link-to. I've created an example of its use here: http://emberjs.jsbin.com/rinukefuqe/2/edit?html,js,output
{{#-link-to params=(unbound link) hasBlock="true"}}
{{title}}
{{/-link-to}}
The params attribute is what the link-to helper normally bundles your positional parameters onto, although you must use the unbound helper here because the LinkComponent expects params to be an array rather than a value binding object. Additionally, the determination of use as block or inline component is not built into components yet, so you must pass hasBlock="true" unless you include the link text as the first parameter in your array.
Ember ≤ 1.12.x
Although it is not done already, you can manually expose the LinkView component, which is the equivalent of the new LinkComponent.
App.XLinkToComponent = Ember.LinkView.extend();
Then use it like:
{{#x-link-to params=link}}
{{title}}
{{/x-link-to}}
Using unbound and hasBlock="true" are not necessary as the internal logic of LinkView differs from LinkComponent.
I think that isn't possible to pass an array, but you can pass each argument directlly, like the following:
route
var user1 = this.store.find('user', 1);
var data = { data: { link: "users.show", model: user1, title: "User1" } };
return data;
template
{{#link-to data.link data.model.id}}{{data.title}}{{/link-to}}
I hope it helps

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.