问题
Is there any Sails.js (or Node) configuration which can prevent Angular routing from working?
No matter what approach I take, every rout apart from ones in sails' routes.js return 404.
I've tried both 1.2 and 1.3 Angular versions, and I'm using Sails v 0.9.15.
All scripts are loaded in correct order (for example):
<script src="/linker/js/libs/angular/angular.js"></script>
<script src="/linker/js/libs/angular/angular-resource.js"></script>
<script src="/linker/js/libs/angular/angular-route.js"></script>
<script src="/linker/js/libs/angular/angular-sanitize.js"></script>
...
<script src="/linker/js/app.js"></script>
I'm using the ngRoute correctly:
var myApp= angular.module('myApp', ['ngRoute']);
Here are my routes in Angular's app.js:
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/profile',
{ templateUrl: 'linker/views/profile.html', controller: 'MainCtrl' })
.when('/profile-detail',
{ templateUrl: 'linker/views/profile_detail.html', controller: 'MainCtrl' });
}]);
And I'm also using location provider:
myApp.config(function ($locationProvider) {
$locationProvider.html5Mode(true);
});
Additional details:
ng-app and ng-view are correctly placed, and my paths are correct. I can correctly show profile.html with Angular (and also to include data from Sails' Restful API).
Problem is, that I can only do that for routes defined in Sails' routes.js.
Example:
module.exports.routes = {
'/' : {
controller: 'main',
action: 'index'
},
'/signup' : {
controller: 'main',
action: 'signup'
},
'/login' : {
controller: 'main',
action: 'login'
},
'/profile': {
controller: 'users',
action: 'profile'
} //......
So basically, in order to show some html content with Angular, I have to define EXACTLY THE SAME route in Sails' configuration, which makes no sense.
Any ideas? P.S. I'll provide additional data if needed.
回答1:
Try removing the html5 mode to see what happens:
$locationProvider.html5Mode(false);
If you are using your sails application only to provide an API for your Angular app, but you are using the same backend to serve your angular code, then you could prefix all API routes with 'api' in order to prevent having conflicts with angular routes.
Instead of /profile you would have /api/profile
EDIT: I've taken a look into the Sails.js framework and made a small app to test it.
I was able to successfully have routes in angular work that were not defined by sails.
I think there is a misunderstanding of how angular routing works.
If you change the path with window.location or type the url manually, the browser will send a get request to the server. So in your case, there will be a request for /profile or /profilee and the server will look at the available routes and will throw a 404 if nothing matches.
To prevent that, you should actually change the path using angular methods. Angular uses the '#' symbol in the path to prevent the browser of sending requests to the server when the url changes. Browsers ignore changes after the '#' symbol. Or in your case, a similar effect is achieved using the html5 mode. Beware though that using html5 mode can cause troubles when users refresh the page, since then a request will be made to the server (more on how to fix that below).
So, what you should be using to change the paths with javascript is the $location service. In your angular views, you can also use normal anchor tags like, because angular parses those:
<a href="/profilee">Go to profile</a>
Since what you have is a single page application, alls views are handled by the client. All the paths beyond the root (/) are virtual paths created by angular. They usually don't exist in the server. Only the root is available. When using html5 mode that can be a problem.
A way to fix that is to rewrite the routing of the server to serve everything else as if it was a request to the root path. In sails they even suggest how to do that in the config/routes.js:
// What about the ever-popular "vanity URLs" aka URL slugs?
// (you might remember doing this with `mod_rewrite` in Apache)
//
// This is where you want to set up root-relative dynamic routes like:
// http://yourwebsite.com/twinkletoez
//
// NOTE:
// You'll still want to allow requests through to the static assets,
// so we need to set up this route to ignore URLs that have a trailing ".":
// (e.g. your javascript, CSS, and image files)
'get /*(^.*)': 'UserController.profile'
Regarding the API in sail, you can configure a prefix inside the config/controllers.js file:
/**
* `prefix`
*
* An optional mount path for all blueprint routes on a controller, including `rest`,
* `actions`, and `shortcuts`. This allows you to continue to use blueprints, even if you
* need to namespace your API methods.
*
* For example, `prefix: '/api/v2'` would make the following REST blueprint routes
* for a FooController:
*
* `GET /api/v2/foo/:id?`
* `POST /api/v2/foo`
* `PUT /api/v2/foo/:id`
* `DELETE /api/v2/foo/:id`
*
* By default, no prefix is used.
*/
prefix: '',
来源:https://stackoverflow.com/questions/22957465/angular-and-sails-routing-configuration