I have a single page app using Dart and Polymer. I'm trying to add a route to another page with route_hierarchical
What I've tried so far was configuring the router like this:
router = new Router()
router.root
..addRoute(name: 'games', path: '/games')
..addRoute(name: 'login', path: '/login')
..addRoute(name: 'home', defaultRoute: true, path: '/');
router.listen();
I've found that I can use
new Router(useFragment: ...);
to enable the hashbangs in the URLs or not. The problem is that when I don't use hashbangs, I can't access a page using the URL directly. (meaning the app routes me when I click on buttons and such). Is there a way of having sharable URLS with no hashbangs? I've seen AngularJs using something like
$locationProvider.html5Mode(true)
to remove the hashbangs and still have sharable URLs... I don't know if I really should bother having URLs without hashbangs though. I've read having them is going to give me trouble with SEO, is that right?
I'm only using Polymer and route_hierarchical right now, and didn't want to go for angular.dart just for routing.
You need to use a router on the server side too when you want to use URLs without fragments.
see also
httpd.conf and HTML5 pushstate()
Angular dart bookmarking views
AngularJS routing without the hash '#'
Related
In our team, we want to use angular-ui-router to assign a "state" by reading the url without hashbangs or html5mode, so that 1. We programmatically assign controllers based on "normal" urls and 2. We support ie9
We can't support hashbangs (which would give use ie9 support) because we are running this on a "non-spa website" and the urls are rendered server side. We literally just want to assign a state by reading a normal url on page load.
This seems trickier than I previously thought. Consider the following routes:
//Parent view
.state('abc', {
abstract: true,
controller: 'MainController'
})
//Search
.state('abc.Search', {
url: '/booking/search',
controller: 'SearchController'
})
Here is the goal: We want the whole path http://website.com/booking/search to pick up the state NOT http://website.com/#/booking/search, and we can't remove the # by adding html5mode.
If we try to add html5mode the page keeps refreshing in ie9 (we dont support ie8).
Now I know that we can remove state-routing and go back to adding ng-controller to the template, however we are in a unique position where we need to be able to programmatically assign controllers based on the url. This is the advantage on using angular-ui-state router.
Thanks in advance.
I'm trying to create an ASP MVC 4 project with Ui-Router, however I've come across a problem.
My current server-side routing configuration looks like this:
// Controller/Action route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}");
// Redirect any other routes to Site/Index so AngularJS can handle routing
// Place routes above this otherwise they will be ignored
routes.MapRoute(
name: "Catch-All Redirect to Index",
url: "{*url}",
defaults: new { controller = "Site", action = "Index" }
);
And client-side
angular.module('loluk.home')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('index', {
url: '',
templateUrl: '/home/index'
});
}]);
Site/Index, the redirect action, simply contains the HTML file that has the ng-app directive. Any other actions/controllers will return API data, or a template. So, in my case, I have Home/Index which returns a template containing <h1>Hello, World!</h1>.
This is all fine and dandy if one of my states in ui-router requests "home/index" via templateUrl for my application. However, the problem I have now is that if I browse to http://localhost/Home/Index, I will see the template in it's raw form - rather than what I am expecting to see, which is the whole application in the Home/Index state. This makes sense as that is how I have configured it.
I initially thought "OK, well I can solve this problem by redirecting everyone to Site/Index (where the main file is stored) and using inline templates". Well, this works well, until you consider that
The HTML file containing index.html is going to get ridiculously large and contain every template
This breaks escaped_fragment crawling
So right now I am at a loss of how to make this work; I could use inlining, but that would make web pages load slowly and break SEO. I could stick with what I have.. but that will break any bookmarks that end-users create.
Making template calls a ChildActionOnly worked well until the fact that ChildActionOnly will return a server 500 (rather than a redirect), and UI-Router appears to not qualify as a "Child Action" as requesting the template through templateUrl also triggered the server 500.
I did come across this question, however it doesn't express how exactly to solve the template situation.
Another avenue I have just pursued is having a templates area that contains all of my templates, and an api area that contains all of my api details (/templates/ and /api/ respectively). This solves the whole reloading page problem, though I am still unsure of how to approach the escaped_fragment crawling from this point of view.
I've accomplished this by creating two Areas in MVC - one for API that routes to /api/ and one for Templates that routes to /templates/. AngularJS will make calls to /template/{controller}/{action} which will return a plain HTML view, and make RESTful calls to /api/{controller} for retrieving data.
It's not a perfect solution but it works.
I am currently rewriting an older version of and application where HTML is mostly generated server-side in angularJS.
Only some parts of the page are not powered by AngularJS while some of client side logic is still plain JavaScript. For URL routing we use UI-router
One of the cases is tabs that are used across all the application. It's current implementation contains above all rewriting location hash like this: myapp_url?foo=bar#1, myapp_url?foo=bar#2 etc.
Note - no slash "/" in hash part.
In my case angular block is in one of the tabs is not visible by default. So when user clicks tabs on a page, URL is changed to smth like myapp_url?foo=bar#TAB_id, which is not understaded by UI router and it redirects the app ( not the whole page but a angular-powered block) part to a 404 state.
Angular UI router relies on Url mask like myapp_url?foo=bar#/my_route - with slash symbol in hash part - so that could be a trigger.
I am asking how/where I could add this kind of check - for angular part whether to act or skip on url change?
I've solved it by creating a state with empty url, which does not interfere with url hash changes by javascript outside angularJS app.
$stateProvider
.state("base.emptyState", {
url: "",
template: '';
})
I'm getting really frustrated with configuring the Routing on our app, which is using sailsJS and angularJS.
The problem is, that the browser doesn't know about angular, so any request like /login returns a 404 Error from sails. I need a solution, to keep the sails routes from the angular ones,
One solution would be to disable html5Mode, but i really don't like the look of URLs with the /#/ which is typical for angular.
I have researched a lot on this and haven't yet found a good answer or maybe a working project for this.
Is what I am trying to do even possible right now?
If you're using HTML5 mode with Angular, then you need to configure your web server (in this case SailsJS) to respond with your index.html file for requests to /login or any arbitrary routes.
If you navigate directly to http://localhost:3000/login in your web browser (assuming you're running Sails on localhost:3000), Sails needs to respond with your index.html so that your Angular app can bootstrap and then display the appropriate route. Then, subsequent links that the user clicks on in your app will be intercepted directly by the Angular router instead of Sails directly.
Angular has documentation about making HTML5 mode work correctly here.
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows Angular to differentiate between the part of the url that is the application base and the path that should be handeled by the application.
I have been unable to find any articles on Backbone.Marionette using pushstate withOUT Node.js, or grunt, or require where a serious discussion is made about URL handeling. A user should be able to send a link to an internal page to her grandmother and have the link work, for example. The pushstate functionality seems uniquely ill-suited to the real world. Can someone comment and perhaps provide some links to serious articles on the subject?
Generally speaking, there's really just 2 things you need to do...
Tell Backbone to use pushstate by calling Backbone.history.start({ pushState: true });. You may also need to add something like root: 'myApp' to that parameter if your Marionette app is served from http://example.com/myApp instead of directly on http://example.com.
Configure your web server so that no matter what URL the user requests, the same content (your Marionette app) is returned (without doing a redirect).
The catch is that #2 is implemented differently depending on what type of web server you are using. And you haven't told us what stack you're on. In ASP.NET, for example, this can be handled by setting up a 'catch all' route by adding something like this to your RouteConfig.cs file:
// all requests (except those explicitly handled by another route)
// go to HomeController.Index and then the Backbone router examines
// the URL client-side to determine client-side what to do
routes.MapRoute(
name: "Default",
url: "{*clientRoute}", // this is wildcard which captures the entire URL
defaults: new { controller = "Home", action = "Index" }
);
Other web server stacks will have different ways of achieving the same type of thing.