I've defined some properties in a controller for a pagination:
import Ember from 'ember';
export default Ember.ArrayController.extend({
limit: 1,
skip: 0,
pageSize: 1
}
});
I'd like to access limit in the Route's model-function but I don't know how.
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
console.log(this.get('controller').get('limit')) <- doesnt work for example
return this.store.find('post', {limit: 1,
sort:'createdAt desc'});
}
});
Maybe you should take a look at the queryParams option (http://emberjs.com/guides/routing/query-params/).
With query params you can set the limit to be a query param in your URL like http://yourdomain.com/someroute?limit=15.
Your controller will become:
export default Ember.ArrayController.extend({
queryParams: ['limit'], // Here you define your query params
limit: 1 // The default value to use for the query param
});
You route will become:
export default Ember.Route.extend({
model: function(params) {
return this.store.find('post', {
limit: params.limit, // 'limit' param is available in params
sort:'createdAt desc'
});
}
});
Alternative:
If you don't want to use query params, another solution might be to define the limit property in one of the parent route's controller. By doing so you can access the property in the model hook by doing:
this.controllerFor('parentRoute').get('limit');
Related
I'm trying to do something like this in my routes:
this.route('products', { path: "/products/*choises"}, function() {
this.route('promotion', {path: "/promotion/*offers"});
});
product route:
offerPath: function(params){
this.transitionTo('product.promotion', params);
}
The problem is that it doesn't matter the promotion that I visit, the app thinks is part of the products route.
How can I do this? I need them to be nested.
Update:
You can use beforeModel(transition) hook in router to check what's in the url.
http://example.com/products/manufacturer-209/series-881/tag-17143/none/494822/flawless
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel(transition) {
console.log(transition.params.products.choises)
// if you use this url: http://example.com/products/manufacturer-209/series-881/tag-17143/none/494822/flawless
// console log would be: "manufacturer-209/series-881/tag-17143/none/494822/flawless"
}
});
At least you have the rest of the url so, you can filter out the important information and redirect with this.transitionTo() to the exact place.
You could have the following route:
http://example.com/products/123/promotions/456
or
http://example.com/products/awesome_souce/promotions/monday_deal
In the first case, your route would look like this:
this.route('product', { path: "/products/:product_id"}, function() {
this.route('promotion', {path: "/promotions/:promotion_id"});
});
In the second case, maybe like this:
this.route('product', { path: "/products/:product_name"}, function() {
this.route('promotion', {path: "/promotions/:promotion_name"});
});
Finally, your route handlers can download the proper models (example for the first case):
// app/routes/product.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('product', params.product_id);
}
});
---
// app/routes/product/promotion.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
// you can get access to the parent route model if you need for the api query
const product = this.modelFor('product');
return this.store.findRecord('promotion', params.promotion_id);
}
});
If you need only the param from the product route, instead of returning a whole record, for example you can just return params.product_name, so you will have access to a string with this.modelFor('product') in a subroute level.
I'm newbie in ember.js and i'm trying to sort a list of products in my app.
I have a route catalog/category.js:
import Ember from 'ember';
export default Ember.Route.extend({
queryParams: {
ordering: {
refreshModel: false,
},
},
model (params) {
return Ember.RSVP.hash({
categories: this.store.peekAll('category'),
category: this.store.peekRecord('category', params.category_id),
});
}
});
and controller catalog/category.js:
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams: ['ordering'],
ordering: null,
sortedProducts: Ember.computed.sort('model.category.products', 'ordering'),
});
Link passes a parameter:
{{#link-to 'catalog.category' (query-params ordering='price')}}Price Asc{{/link-to}}
ordering parameter is setting to price and it doesn't work. But when I manually set the ordering parameter to ['price'] - everything works as expected.
Can anyone suggest how to fix it?
ordering parameter is setting to price and it doesn't work. But when I
manually set the ordering parameter to ['price'] - everything works as
expected.
There is a difference between string:price (set by query param) and array:['price'] (set by you manually).
You need another property which will create that array for you:
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams: ['ordering'],
ordering: null,
orderingObserver: Ember.on('init', Ember.observer('ordering', function() {
let ordering = this.get('ordering');
let array = [];
if (ordering) {
array.push(ordering);
}
this.set('orderingArray', array);
})),
sortedProducts: Ember.computed.sort('model.category.products', 'orderingArray'),
});
isn't it supposed to work "out of the box"?
It works with arrays of properties - http://emberjs.com/api/classes/Ember.computed.html#method_sort.
I'm trying to use setupController method to pass some data to the controller from the route and it only works if the controller is a singleton.
The setupController method is called in both situations but the variables are only set on the controller if it's a singleton.
How can I pass data from a route to a transient controller?
Here's a twiddle:
http://ember-twiddle.com/ba55734e925664e363f4
Uncomment/comment the following line to toggle between singleton/transient:
//application.register('controller:application', 'ApplicationController', { singleton: false });
I have not been able to find any information about whether or not this should work. I'm using Ember 1.13.6.
controllers/application.js:
import Ember from 'ember';
export default Ember.Controller.extend({
appName:'Ember Twiddle'
});
initializers/application.js:
export function initialize(container, application) {
//application.register('controller:application', 'ApplicationController', { singleton: false });
}
export default {
name: 'application-init',
initialize: initialize
};
routes/application.js:
import Ember from 'ember';
export default Ember.Route.extend({
setupController: function(controller,model) {
this._super(controller,model);
controller.var1 = "Variable 1";
}
});
templates/application.hbs:
<h1>Welcome to {{appName}}</h1>
<br>
<br>
{{var1}}
<br>
This appears to be an actual bug, since the instance of the controller is different from the instance you have in setupController and the one backing the view.
A workaround would be overriding the renderTemplate hook on your route to pass the instance of the controller versus a string reference which is looked up by default (and creating a new instance of the controller!).
export default Ember.Route.extend({
setupController(controller, model) {
this._super(...arguments);
controller.set('var1', 'foo');
},
renderTemplate(controller, model) {
// note: don't call super here
this.render('application', {
controller: controller,
model: model
});
}
});
I would like to access a global query param in a nested route (child route).
The localisation setting is stored in a Global Query Param on the Application Route:
App.ApplicationController = Ember.Controller.extend({
queryParams: ['localSelected']
});
Now I would like to access that value in my App.IndexRoute
App.TranslateRoute = Ember.Route.extend({
model: function(params){
params.localSelected **NOT AVAILABLE**
}
});
Finally found a solution by setting a global variable every time the query params updates.
In the Application Controller
App.ApplicationController = Ember.Controller.extend({
queryParams: ['localSelected'],
localSelectedOberver: function(){
App.set('localSelected', this.get('localSelected'));
}.observes('localSelected').on('init'),
localSelected: "en"
});
And because the controller initializes to late, you also need:
App.ApplicationRoute = Ember.Route.extend({
model: function(params){
App.set('localSelected', params.localSelected)
}
)}
})
Then whenever you need to know the localisation query param value you can just go:
App.get('localSelected');
I read at
http://emberjs.com/guides/controllers/
the following code:
I have a search box and want to send the value of the search box to the SearchController.
App.ApplicationController = Ember.Controller.extend({ // the initial
value of the `search` property search: '',
actions: {
query: function() {
// the current value of the text field
var query = this.get('search');
this.transitionToRoute('search', { query: query });
} } });
How can i get the query parameter in the SearchController and then show it in search.hbs?
I am working with ember- cli.
The router is
import Ember from 'ember';
var Router = Ember.Router.extend({
location: NENV.locationType
});
Router.map(function() {
this.route('search');
});
export default Router;
I set up a route under routes/search.js
export default Ember.Route.extend({
model : function (params) {
console.debug("hi");
return params;
},
setupController: function(controller,model) {
var query = model.query;
console.debug("query is");
console.debug(query);
}
});
When debugging i get an error:
ember More context objects were passed than there are dynamic segments
Thanks,
David
You need to define your search route to be dynamic, so if you change your route definition to something like this
Router.map(function() {
this.resource('search', {path: '/search/:query});
})
This should work as you are expecting. Let me know if anything.
Cheers!