一步一步route過去可以,地址欄直接寫url怎么就找不到了呢?
這關乎於Nodejs的express路由規則(http://hm4123660.iteye.com/blog/2195035)
express 封裝了多種 http 請求方式,我們主要只使用 get和post,可以使用 app.all 獲取所以請求方式,回調函數有兩個參數分別是 req 和 res,代表請求信息和響應信息。
例如:
獲取表達post的參數
var username=req.body.name;
獲取get參數
訪問URL:http://localhost:3000/test?id=110&password=120
獲取代碼:
app.get('/test',function(req,res){ res.send("id: "+req.query.id+" password: "+req.query.password); })
一. *通配URL
例如:
app.get('/test/*',function(req,res){ res.send(req.originalUrl);
*號可以通配URL為localhost:3000/test/.......的URL
二. /:id的占位標識符URL
例如:
app.get('/test/:userid',function(req,res){ res.send("userid: "+req.params.userid);
三.next()權限控制轉移
express的路由控制有個next()功能,在定義了多個路由的時候,使用next對匹配的url會按順序執行,
如果不使用next進行權限轉移,只會執行第一個滿足的路由規則。
<span class="token comment">next() 函數用於將當前控制權轉交給下一步處理,如果給 next() 傳遞一個參數時,表示出錯信息</span>
例如:
app.get('/test/*',function(req,res,next){ //res.send("userid:");//要進行轉移,不要響應客戶端 req.temp="給你控制權"; next();//把權限轉移到下一個路由 }); app.get('/test/next',function(req,res){ res.send("content: "+req.temp); })
訪問URL:http://localhost:3000/test/next滿足這兩個路由規則
next()一般用來編寫中間件
- 中間件一般不直接對客戶端進行響應,而是對請求進行一些預處理,再傳遞下去;
- 中間件一般會在路由處理之前執行;
比如:
app.get('/*', function (req, res, next) {
// 就是不能有這一句
// res.sendFile(__dirname + '/../dist/index.html');
// 上面這一句其實是無關緊要的,並不需要它就可以訪問第一個路由
req.temp="給你控制權";
next();
});
app.get('/test',function(req,res){
res.send("content: "+req.temp);
})
靜態目錄其實已經在app.use的時候指定了
app.use('/', express.static(__dirname + '/../dist'));
app.use('/scripts', express.static(__dirname + '/../node_modules'));
res.sendFile之后next或者在獲取了控制權的下一級路由中寫這一句,都會報Forbidden的。
這是單純node中路由的跳轉,在angular2中,不會去加載另一個html文件,還是要用angular自己的方式實現,參看
Angular2 路由教程 3 - 子模塊以及異步加載(https://gold.xitu.io/entry/58523aa91b69e6006c7e63ac)
如果像一般的starter那樣把todo相關的路由定義在一個文件中,然后在app的路由定義中把所有路由合並到一起。
todo.routes.ts
的內容如下:
然后在app.routes.ts
中定義一個路由模塊:
const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, //此處省略...TodoRoutes
最后,在AppModule里面引入這個路由模塊。
這種方式實現的路由無法實現子模塊的延時加載,要實現延時加載,首先要將todo模塊的路由修改成子路由模塊,也就是要修改todo.routes.ts
:
這里定義了一個子路由模塊,TodoRoutingModule
,它使用RouterModule.forChild(TodoRoutes)
來創建。跟整個App的路由模塊比較的話,主路由模塊使用RouterModule.forRoot(routes)
來定義。
定義好了子路由模塊,在子模塊里面引入它既可:
這樣就定義好了一個子模塊。當用戶打開/todo/list
或/todo/detail/*
時,這個子模塊里面的相關頁面就會展示,它也不會跟其他模塊有任何交互。也就是說,進入和離開這個子模塊,都是通過路由跳轉實現。這個子模塊也是完全獨立的,可以獨立開發,也可以很容易就用到其他應用里面。
coockbook參看http://blog.csdn.net/qq_36181008/article/details/53331685
另外,使用`ActivatedRoute`拿到當前路由獲取參數:
ngOnInit() {
this.route.params.subscribe((params) => {
this.createPies();
this.onTopListFilterChange(params['id']);
});
};
但如果是在`children`中指定的component要拿到路由參數就沒那么容易了,這時候再使用ActivatedRoute根本拿不到參數,我猜應當是在Angular2中一個ActivatedRoute對應一級路由配置,所以我們需要找到父級路由,由父級路由去拿參數。這時我們需要借用Router類的routeState屬性的parent方法:
this.router.routeState.parent(this.activatedRoute).params.subscribe(params => {
this.getDetailsById(params['id']);
})
上面的問題原文地址:http://www.cnblogs.com/dojo-lzz/p/5883408.html
默認情況下Angular2將所有的代碼打包成一個文件,目的是為了提高應用的流暢性,但是如果是運行在mobile中的app,加載一個大文件可能會過慢,所以rc5提供了一種延遲加載方式,例如:
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
其中,path指明路徑,loadChildren指明使用延遲加載,'app/crisis/crisis.module#CrisisModule'指明了模塊的路徑,和模塊的名稱, 如果是用 export default 的話,這里可以不需要表明名稱,只需要路徑。
但是上面的語法在有些版本不能正確的懶加載,甚至使子路由失效,需要用lambada表達式:
const routes = [
{path: '', component: HomeComponent},
{path: 'test', loadChildren: () =>TestModule},
{path: 'amway', loadChildren: () =>AmwayModule }
];
絕對很好用,來自stackoverflow
路由器根據路由狀態來實例化組件並把他們放到合適的路由組出發點上。
@Component({
template: `
...
<router-outlet></router-outlet>
...
<router-outlet name="popup"></router-outlet>
`
})
class MailAppCmp {
}
如‘/inbox/33/message/44(popup:compose)’,首先實例化ConversationCmp放到主<router-outlet>中,然后實例化MessageCmp放到name為popup的<Router-outlet>中。
現在路由器對URL的解析過程完畢。但是如果用戶想從MessageCmp中跳轉到別的路由狀態該如何做呢?Angular2提供了兩種方式。
一種是通過router.navigate方法來導航:
@Component({...})
class MessageCmp {
private id: string;
constructor(private route: ActivatedRoute, private router: Router) {
route.params.subscribe(_ => this.id = _.id);
}
openPopup(e) {
this.router.navigate([{outlets: {popup: ['message', this.id]}}]).then(_ => {
// navigation is done
});
}
}
一種是利用router-link方式:
@Component({
template: `
<a [routerLink]="['/', {outlets: {popup: ['message', this.id]}}]">Edit</a>
`
})
class MessageCmp {
private id: string;
constructor(private route: ActivatedRoute) {
route.params.subscribe(_ => this.id = _.id);
}
}
詳細閱讀http://www.cnblogs.com/keatkeat/p/5810987.html
最后問題解決了還是要配置node的express模塊,也就是之前常常看到含有__dirname的部分:
var path= require("path");
var app = express();
app.get('/*', function (req, res, next) {
//res.sendFile(__dirname + '/../dist/index.html');
res.sendfile(path.join(__dirname, '../dist', './index.html'));
req.temp="next";
//next();
});
簡言之就是需要join一下path和index
*通配符也是很關鍵的。
參考文章http://www.cnblogs.com/stoneniqiu/p/5669419.html
延伸閱讀http://www.cnblogs.com/darrenji/p/4981505.html
略:
var path= require("path");
app.get('/*', function (req, res, next) {
//res.sendFile(__dirname + '/../dist/index.html');
res.sendfile(path.join(__dirname, '../dist', './index.html'));
});