Closed henrytao-me closed 11 years ago
Use ui-sref
directive. Look at API reference.
Hi! I found this https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
Look good. But it doesn't work. I can not find any ui-sref directive in here http://angular-ui.github.io/ui-router/release/angular-ui-router.js
Thanks!
OK! I found ui-sref in development version! Thanks!
ui-sref doesn't fix this problem.
My problem above is not dynamic generate href. It is html5Mode combine with ui-router, automatically.
In ui-router:
In original angular router:
The point is that with uisref you don't specify href at all. The href is generated and will use # if html5mode is disabled. That's the only way we support both modes dynamically.
I write a directive like this: to overcome this issue:
Usage: just put hash # in ehref Dashboard. ehref Directive will automatically check html5Mode enable or disable.
angular.module('directive.ehref', []).config(function($locationProvider){ this['directive.ehref'] = $locationProvider; }).directive('ehref', function(){ var config = this['directive.ehref']; return function($scope, $element, $attrs){ if(config.html5Mode() === true){ $element.context.href = $attrs.ehref.replace('#' + config.hashPrefix(), ''); return; }; $element.context.href = $attrs.ehref; }; });
Hi Timkindberg!
Does uisref support hashPrefix when developer set on $locationProvider.hashPrefix('!')?
That I'm not sure of.
I read the ui-router v0.0.2. I found this return !$locationProvider.html5Mode() && url ? "#" + url : url;
So I think it still doesn't support hashPrefix!
@henrytao-me, check out this SO answer. I'm using this solution and it works.
Your config function would look something like:
function ($locationProvider, $provide, $stateProvider) {
//comment out the decorator function for html5mode
//uncomment the decorator function for forced hash(bang) mode
// $provide.decorator('$sniffer', function($delegate) {
// $delegate.history = false;
// return $delegate;
// });
$locationProvider.html5Mode(true);
// etc.
add this line to app.config:
$locationProvider.html5Mode(true).hashPrefix('!')
and include this line in the head of index.html:
<base href="/">
Incase the above fails and your using yeoman-angular try this: http://jjt.io/2013/11/16/angular-html5mode-using-yeoman-generator-angular/
@jasonshark, Thank you for your answer.
@jasonshark Thanks a lot for your answer. Adding
:+1:
@jasonshark , thank you very much for your answer
Hi I'm using html5 url mode to hide hash tag in my angular URL. If i refresh or copy/paste URL to other tab on browser its showing 404 error page not found
Please help me out
@mahesh5b5, minutes ago I bumped into the same issue and I realized that it is in fact the expected behavior and here's the explanation: When you tell the $locationProvider to use the html5 mode, the route URLs look as desired and work fine when you navigate to them by "clicking" the relevant links. example: you can navigate from http://myWebsite/home to http://myWebsite/about by clicking the anchor tag as this navigation is orchestrated by the angular-ui-router. However once you are on the destination URL http://myWebsite/about, refreshing it will cause the browser to make a fresh "get" request to that URL and is not orchestrated by the angular-ui-router. This fresh request should be served by the server "myWebSite". Hope this explanation helps :)
@shardoo So if I will send somebody a link to http://myWebsite/home he/she will get 404, because a user did not enter myWebsite from the root location ("/"). Is there a fix for this behavior so angular will recognize request and will generate content?
This is because when you submit the link it makes a request to that route on the server, when angular is using client side routing. To enable html5 mode, you need to serve the index on all routes for html5 mode. Like this for a node app.
// This is a server file
app.get("*", function(req, res) {
res.render("./index.html");
}
Angular UI router html5 mode works by say...
// This is in your app module config.
$locationProvider.html5Mode(true);
// This is in your index.html head.
<base href="/" />
This is all you need for the pretty urls essentially, the issue is if you navigate to a route with out the hash prefix and submit a link to the server, it will cause a server request for that route. So like I mentioned about you need to render the index on all routes submitted to the server.
@isaiahgrey93 Thanks for your input. You are very right. I fixed this problem on the server. I render all my urls to index.html page. By doing that angular reads the url, and loads appropriate state. Regards ;)
i had deployed my client on firebase server so didn't make redirect all routes to index.html so what to do?
Have you set in your apaceh/nginx virtualhost conf file html5 handling ? Here is my below set up
### serve index.html as django app
<Directory /srv/www/compare/htdocs/core/frontend/templates>
## link: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
## link: http://stackoverflow.com/questions/869092/how-to-enable-mod-rewrite-for-apache-2-2
RewriteEngine on
# Rewrite everything else to index.html to allow html5 state links
# Don't rewrite files or directories
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^ index.html [L]
</Directory>
my app hosted on firebase not apaceh/ngix??
Then I cannot help you. I heave no experience with firebase.
@shardool Any suggestion how you solved your problem ?. I am also having the same issue
Does this not help? https://www.firebase.com/docs/hosting/guide/url-redirects-rewrites.html
For those who are using Angular JS with Laravel 5 and facing page not found issue after page refresh while implementing @isaiahgrey93 solution, add following line in your route.
Route::any('{path?}', function()
{
return File::get(public_path() . '/angular.html');
})->where("path", ".+");
i'm working in a ionic application, how i can configure it from the server site?
Thanks :+1:
any idea how to make it work with codeigniter?
Hi,
Seems like page refresh not working in my url "http://anaoh.com/about" with enabled html5 mode.
Can you please suggest me what I am missing.
Raja K
@cullsin, you need to set on you your server routing that all pages will go to the home page(you default one).
Also, tell us what you are using on the server side(framework or language).
P.S - If any one is using Codeigniter 3 this is my solution.
Hi,
I am using Phalcon REST Framework in the backend so it serves only data. I have configured apache Rewrite Engine too.
<IfModule mod_rewrite.c>
RewriteEngine On
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ /index.html [L]
</IfModule>
Hi,
This is working greate. I had a code issue in the loading. Sorry for the confusion.
Raja K
This solution is working for Rails 4.x.x and AngularJS 1.5.7.
app.coffee
angular.module('myApp').config( ($stateProvider, $urlRouteProvider, $locationProvider) ->
$stateProvider.state() # Your states here
$locationProvider.html5mode true
application.html.erb:
<head>
<title>My Wonderful World</title>
<base href="/">
routes.rb:
root 'home#angular'
get '*path' => 'home#angular'
home_controller.rb:
class HomeController < ApplicationController
def angular
render 'layouts/application'
end
end
An alternate approach:
application_controller.rb:
class ApplicationController < ActionController::Base
...
def index
end
routes.rb
root 'application#index'
get '*path' => 'application#index'
My issue was that my base url looked like this:
<base href="/">
So had to add a /
to my first state url:
$stateProvider .state('index', { url: "/", ...
I am having a problem with the HTML5 and ui.router If I activate the HTML5 like: $locationProvider.html5Mode(true); my URLs looks perfect (without #!) but then if I refresh the page, its gets blank.
If I deactivate the HTML5 (just out comment: // $locationProvider.html5Mode(true);) I can refresh and I do not lose the page, but I have the ugly URL like: http://localhost:50895/#!/addcontact
I added the following rewrite method in my Web.config (I am in ASP.NET) but it crash the application:
<rewrite>
<rules>
<rule name="RewriteRules" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
Any idea?
I'm having this problem too. Cannot refresh page with html5Mode(true) I use Express serving index file like
app.all('/*', function(req, res, next) {
res.sendFile('index.html', { root: __dirname });
console.log("send index");
});
but there was no luck.
Did you follow steps I outlined above, including:
root 'your_controller#your_method'
get '*path' => 'your_controller#your_method'
in routes.rb
?
No. Actually I use Node and Express, not Rails.
have you tried
$locationProvider.html5Mode({
enabled: true,
...
}).hashPrefix('!');
Yes. I have hashPrefix('!') for sake of SEO.
was try to change to
res.sendFile(path.join(__dirname + 'index.html')); or + '/app_client/index.html'
still no good.
This was my static file serve on upper line.
app.use(serveStatic(path.join(__dirname, 'public'))); app.use(serveStatic(path.join(__dirname, 'node_modules'))); app.use(serveStatic(path.join(__dirname, 'app_client')));
I have same problem with macsermkiat. I'm using MEAN Stack, Node for back-end and Angular JS for front-end. I'm also use : if(window.history && window.history.pushState) { $locationProvider.html5Mode({ enabled : true, requireBase : false }).hashPrefix('!'); in my app.route.js and base href="/" in my home.html. It can remove the hash # but when i try reload i get an error can get/state-name ... Any solution for this ?? thanks for your help }
After 4 hours !! Problem Solve :D
How?
Back-end : In your app.js : app.get('/any-thing-you-want/*', function (req, res) { res.sendFile(path.join(__dirname, './views', 'home.html')); // change this });
Front-end : In your home.html ( or index.html ) add this line base href="/any-thing-you-want" (same string with your app.js) In app.route.js $urlRouterProvider.otherwise('/any-thing-you-want/'); .state('app') url : '/any-thing-you-want/' ...... ......;
if(window.history && window.history.pushState) {
$locationProvider.html5Mode({
enabled : true,
requireBase : false
}).hashPrefix('');
}
done.... change ui-sref or href in front-end from #/... to any-thing-you-want/..... or just use $state.go(...) Sry for my bad English..
@severus-ebay : This configuration works for me when I deploy the application on IIS. It doesn't work(reason I don't know) when I run this application from Visual Studio.
Also, you can try replacing <action type="Rewrite" url="/index.html" />
with <action type="Rewrite" url="/" />
You can also check the answer for this question and try this configuration, may be it will help: https://stackoverflow.com/questions/27749776/angularjs-with-html5modetrue-on-iis-and-default-document
Hi index.html `<!DOCTYPE html>
Hi all! How can I make angular ui-router work with html5mode=true automatically? I mean:
In angular, you have the link like this href="#/abc". If you set html5mode=true, it automatically redirect to /abc when you click on link abc. If html5mode=false, it keeps #/abc. So, nothing need to change in your html code.
In angular ui-router, if you plan to enable html5mode=true, you need to change all link from html code to something like: (without #). If html5mode=false, you need to have # in url.
So, how to fix it in angular ui-router? Thanks for advice!