Can ui-router handle multiple parameters in AngularJS? - javascript

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.

Related

Using the same URL for multiple nested ember routes

I have a case using Ember where I want to make the top level URL available (ie. localhost:4200/demo), and have all the routes underneath also display the same URL (localhost:4200/demo). So the route file, if possible would look something like:
this.route('demo', function() {
this.route('one', { path: '/' });
this.route('submit', { path: '/' });
});
I understand that ENV.locationtype can be set for the whole app, but is there a way to conditionally set this for specific URLs underneath a parent URL?
Generally when you end up hitting major snags like this it is because Ember is implicitly trying to tell you that what you are doing isn't a good idea.
Is there a particular reason that you don't want your sub-routes to affect the URL in any way? Could you get by with random values in the URL if your prime purpose is to obfuscate things?
Ember uses the URL to work out what state things should be in in your app. If you don't want to use the routes at all you wouldn't have to, but then at that point you are dealing with a nested hierarchy of components that you have to switch between yourself. Which would in essence be akin to using React without a router ...
By default, Ember can manage URLs, or it can be set to not manage them, but it seems like the desired intent is to have it do both in a single environment, which is not logically allowed.
If none is declared for ENV.locationtype, then Ember's default URL management is turned off. This is an "environment-wide" configuration.
If the Ember Router is being used to map nested routes, and default URL management is in play, then observe that you cannot have the same URL path defined for multiple, sibling, child routes.
A further observation, is that your attempt above is tapping into functionality governed by the single index route that is available at every nesting level within the Router map. However, a route cannot have multiple index routes. Only the last one defined will be recognized.
Router.map(function() {
this.route('demo', function() {
this.route('one', { path: '/' }) // <-- this is over-ridden by "submit"
this.route('submit', { path: '/' }) // <-- this defines an "index" route for demo
})
})

Parameters in URL using Angular's UI-Router, issue with .otherwise

I want to search on my page. Actually, my code is
$stateProvider
.state('aaa', {
url: '/aaa',
templateUrl: 'client/parties/views/aaa.ng.html',
controller: 'Aaa'
})
$urlRouterProvider.otherwise("/default");
And now, I want to search on my page, but the params MUST working with the URL.
How to use params when I have $urlRouterProvider.otherwise?
Actually, everything after /aaa/ in URL causes redirect to /default.
Important thing: I have more than 20 parameters, but when there're not selected, I don't want to pass it via URL. This is important because I think I can't do something like url: '/details/:param1:param2:param3:param4',
Can you help me?
Looking at the documentation for ui-router, it doesn't seem like it is possible to not have it redirect without having at least one parameter defined on the state's route.
To accomplish what you want, I think the best is to use a catch all parameter of some sort. It's either that, restricting deep-linking, or reducing the amount of parameters and manually defining it.
Define a catch all parameter as shown below. In this case the parameter is path redirects will not take place if there is nothing after "/files/":
'/files/{path:.*}' - Matches any URL starting with '/files/' and captures the rest of the path into the parameter 'path'.
'/files/*path' - Ditto. Special syntax for catch all.
Define one parameter on a new route, and then split the one parameter into multiple parameters in the controller.

emberjs using multiple paths / urls for one route

In Ember I can use this:
App.Router.map(function() {
this.route('accomodations');
});
so if one goes to /accomodations it will load that view.
I can also add:
App.Router.map(function() {
this.route('accomodations', { path: '/travel' });
});
so if one goes to /travel, it will go to the same view.
I want to be able to have /accomodations and /travel go to the same view? is this possible?
I know that this:
App.Router.map(function() {
this.route('accomodations');
this.route('accomodations', { path: '/travel' });
});
Will do what I'm asking, but if they go to accommodations, it should show that in the url, it always shows travel. I'm not even sure if the final piece of code is best practice.
You can simply interchange the two route-path definition lines:
App.Router.map(function() {
this.route('accomodations', { path: '/travel' });
this.route('accomodations');
});
The last definition takes the precedence for URL display in {{link-to ...'accomodations'}} and Route#transitionTo('accomodations') in-app transitions, though entering the app by '/travel' will leave the URL as is.
(EmberJS 1.11.3, 2.12.2)
Using redirection
In router.js
App.Router.map(function() {
this.route('accomodations');
this.route('travel');
});
In routes/travel.js
App.TravelRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('accomodations');
},
});
You do not have to put these in separate files (that's just where I would put them).
What this does is register two routes with the router. Pick one of them to be the "main" route, and the other the "alias" route. In this case, accomodation is the main route, and travel is its alias. When the user visits /travel, they get redirected to /accomodation.
This would be the default/ standard Ember way of accomplishing this, and if this sounds good to you, go for this.
Another possible solution
If you do not wish to have redirection happen, for some reason, and want the URL seen by the user to stay the same, but still display the same things, and behave in the same way, this is also possible.
In this case, you would create two of every single Ember unit (route, controller, view, template). The smart way would be to create a base class route, and have both App.TravelRoute and App.AccomodationRoute trivially extend it; create a base class controller, and have both App.TravelController and App.AccomodationController trivially extend it; same for views, if you have them.
Templates, OTOH, are a little trickier, because there is not way to extend them (that I know of). SO what you would need to do, is create either a partial or a component (decided which works better for you), and then reuse that partial/ component in both templates/accomodation.hbs and templates/travel.hbs

Angular ui-router: Can you change state without changing URL?

The multiple nested views functionality of the ui-router is very nice - you can easily jump from one state of your app to another.
Sometimes you might want to change the URL, but sometimes not. I feel like the concept of state should be separate/optional from routing.
Here's a plunker that shows what I mean. This is a fork of one of the plunkers in the ui-router documentation, with 2 minor changes noted below:
.state('route1', {
url: "/route", // <---- URL IS SHARED WITH ROUTE2
views: {
"viewA": {
template: "route1.viewA"
},
"viewB": {
template: "route1.viewB"
}
}
})
.state('route2', {
url: "/route", // <---- URL IS SHARED WITH ROUTE1
views: {
"viewA": {
template: "route2.viewA"
},
"viewB": {
template: "route2.viewB"
}
}
})
This seems to work - the URL stays the same. Again, how much redundant work is done here? Is this an approved/tested usage?
It would be nice if you could omit the url from a state..
UPDATE: You can omit a url from a state. plunker
Update question: Is this an approved/tested usage?
You can absolutely have a state without a URL. In fact, none of your states need URLs. That's a core part of the design. Having said that, I wouldn't do what you did above.
If you want two states to have the same URL, create an abstract parent state, assign a URL to it, and make the two states children of it (with no URL for either one).
To add to the other answer, Multiple Named Views do not use a URL.
From the docs:
If you define a views object, your state's templateUrl, template and
templateProvider will be ignored. So in the case that you need a
parent layout of these views, you can define an abstract state that
contains a template, and a child state under the layout state that
contains the 'views' object.
The reason for using named views is so that you can have more than one ui-view per template or in other words multiple views inside a single state. This way,
you can change the parts of your site using your routing even if the URL does not change and you can also reuse data in different templates because it's a
component with it's own controller and view.
See Angular Routing using ui-router for an in-depth explanation with examples.

Duplicate routes called in Backbone.js

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.

Categories

Resources