I want to have a kind of RESTful URL structure like below:
/accounts
/accounts/account/123
I've set up my routes as such:
MyRouter = Backbone.Router.extend({
routes : {
'/accounts': 'accounts',
'/accounts/account/:account': 'account',
},
accounts: function() {
console.log('accounts CALLED');
},
account: function() {
console.log('account CALLED');
},
});
The problem, is when I go to /accounts/account/123 , both accounts() and account() get called (as the URL matches both routes). I tried a route such as /accounts$, but it doesn't look like it's supported in the routes hash.
Is there a way to accomplish this? Would a manual router.route(route, name, callback) work instead (although I really prefer not to do that).
I got this cleared up by another SO question. I didn't realise that I had to use the router.navigate function strictly.
Using the router programmatically (not via browser bar), those duplicate calls go away. I'm also seeing the expected functions called only once... when using router.navigate.
I still have to find out how to capture back & forward buttons to call those functions. Thanks for the feedback so far.
Try /accounts$ instead. $ is the regex for the end of the string.
Related
I have the View containing some button. When that View becomes activated it should take the some URL parameter (in my case -- site id) and set it to the button attribute "data-site_id". There is a router too in the app. But I don't know how to implement it with the best way. Till now I see 3 supposed solutions:
Extract site id from URL hash. URL is build by such a pattern:
"sites/edit/:id(/:tab)": "editSite",
the question is -- may I use here a router itself (and, if yes then how?) or can not, and should parse it with common JS way? Of course, router & view are two different objects and located in different files/scopes.
Save the site_id in model. But I'm not sure how to store it from router. I think I can create an instance of model, set it as variable under router scope and then treat it as usual, something like this:
(function(app, $, config, _) {
var Model = new app.modelName();
var Router = app.Router = Backbone.Router.extend({
routes: {
"": "start",
//....
"sites/edit/:id(/:tab)": "editSite",
//...
},
//....
editSite: function(id, tab){
Model.set('site_id', id);
}
//....
})(window.Application, jQuery, window.chatConfig, _);
after that I can extract the site id from model in any time I want
Assign a data-site_id attribute to the button just from the router. But this doesn't look as a best practice, right?
So what is your advice?
Your second suggested solution makes the most sense, you could then instantiate your view passing that model to the constructor.
See http://backbonejs.org/#View-constructor
I am writing an app with dynamic content loads. I am using Iron Router and am aiming to avoid Sessions if possible. I wrote the following route bellow:
Router.route('/:publisher',{
name: "publisher",
action: function(){
this.render("Publisher")
},
data: function(){
return Comics.findOne({publisher: this.params.publisher});
}
});
Which works, as it uses .findOne. If I switch .findOne to .find, nothing loads, but there are no errors. Any help is appreciated. Thanks
Note: I looked at this link, but it's sadly not the same problem: findOne works but not get all/find
Use collection.find().fetch() instead of collection.find()
collection.findOne() is approximately equivalent to collection.find({},{limit: 1}).fetch()[0]
Explanation
collection.find() is a cursor, whereas collection.find().fetch() is an array of objects.
I have an app that is currently built to have a static base URL with a parameter at the end. I would like to instead have the base URL default to one vaule, but have the ability to built routes based on several options. So for now its set up as:
.state('ball', {
parent: 'ballLayout',
url: '/ball/{urlName}',
views: {
'cube.head': {
templateUrl: 'partials/views/ball.head.html',
controller: 'BallCtrl'
}
}
});
The static ball value is what I'd like to change. Basically I'd like to have an optional list of incoming URLs that would work, but when nothing is present it defaults to ball. So for instance:
ball/title-of-page
bat/title-of-page
basket/title-of-page
beast/title-of-page
These would all work, and when constructing the URL it would default to ball/
Is something like this possible? How would one go about implementation.
I dont think what I'm asking here can actually be done without having issues with other parameters. Instead Im asking a new question about Regex from incoming links to reroute to my angular URL.
In my application I want to read the parameters user is entering and then I want to use that parameter. http://responsive.beta.postify.com/X I want to read that X value. But first how do I ensure that the router expects a parameter?
My router is like this
Cards.Router.map(function ()
{
this.resource('cards', {path: '/'}, function ()
{
// additional child routes
this.resource('selectImage');
this.resource('message');
this.resource('recipient');
this.resource('orderStatus');
this.resource('thankyou');
this.resource('accountInfo');
this.resource('recentOrders');
this.resource('howTo');
this.resource('faq');
});
});
I want that parameter whenever the app loads. That is going to be my clientID which I would be using to fetch data from server depending upon the client.
Any thoughts on it?
When I do something like this
Cards.Router.map(function ()
{
this.resource('cards', {path: ':clientID'}, function ()
{
// additional child routes
this.resource('selectImage');
this.resource('message');
this.resource('recipient');
this.resource('orderStatus');
this.resource('thankyou');
this.resource('accountInfo');
this.resource('recentOrders');
this.resource('howTo');
this.resource('faq');
});
});
and in my browser if I put like this http://responsive.beta.postify.com/#/26 then its working but if I do like http://responsive.beta.postify.com/26 then it is not working.
To answer your question directly, to use a parameter in a route you would do something like this:
this.resource('cards', { path: '/:user_id' });
Then in your route
App.CardsRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('post', params.user_id);
}
});
This is how you can get a parameter in a certain route. Now as far as your application goes, using the code I posted above should get you that parameter as long as they access the root ('/') of your application on first load and have the user_id in the url.
I would suggest a different strategy maybe for getting the client_id and storing it for later user in your application. For example, in my application I have an Ember.Application.initializer({}) where I store the client_id. All depends on your server configuration and how your app is built, but I would definitely try and get the client_id a different way if you can!
Good luck.
This is a simple question, but I am new to routing and haven't been able to find an answer to this.
I have a Marionette Router (if I intimidate you, its really the same thing as a Backbone Router. Very simple).
sys.routes = {
"app/:id": "onAppRoute",
};
sys.Router = new Marionette.AppRouter({
controller: {
onAppRoute: function(route) {
console.log('Called app route!');
},
},
appRoutes: sys.routes,
});
Backbone.history.start({pushState: true})
This works - if you hit the back button my browser, the url will change within my Single Page Application and will call the onAppRoute function.
However, let's say I open a new browser window and paste in my page url to a certain 'app':
http://localhost/app/myApplication
This doesn't call the onAppRoute function. It doesn't even seem like it should, though, but I really don't know.
I want it to.
I don't know if I am doing it wrong, or if I should just manually fire it by grabbing my page url on page load, parsing it, then 'navigating' to that route. Seems hacky.
Contrary to your intuition, backbone's default behaviour is to trigger matching routes on page load! cf. http://backbonejs.org/#Router - look for the option silent: true. You'd have to specify that for the router to IGNORE your matching routes on page load, i.e. not trigger the corresponding callbacks.
So your problem lies somewhere else: your routes do NOT match the url you have stated as an example. Clearly, you require an :id parameter, trailing http://localhost/app/myApplication. Therefore, http://localhost/app/myApplication/213 would cause your callback to be triggered on page load, given you didn't pass silent: true as an option to backbone.history.start().
If you want to match the 'root' url, i.e. no params, you would define the following route:
routes: {
'/': someFunction
}
The :id part is a parameter, which will be extracted by Backbone.Router and sent as an argument to onAppRoute.
But in your URL you don't have any parameters /localhost/app/myApplication