65.9K
CodeProject 正在变化。 阅读更多。
Home

Angular2 - 路由

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.55/5 (8投票s)

2017 年 1 月 9 日

Apache

4分钟阅读

viewsIcon

30709

Angular2 中的路由。

什么是路由?

路由是 Angular 用来在页面之间导航并在浏览器上显示适当的组件/页面的一种机制。

我有点困惑,你能详细解释一下吗?

好的,使用我们的代码,当你在地址栏中输入时,这个 URI "https:///users"。

Angular 将根据已注册的信息查找将在浏览器上呈现的组件(或网页)。

我们需要向 Angular 注册哪些信息才能查看 "https:///users"?

请从 "https://github.com/techcoaching/angular2.git" 检查代码。

打开 "<root>/src/userRoutes.ts",我们看到如下代码

import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { Users } from "./users";
import { CreateUser } from "./createUser";

let routes: Routes = [
    { path: 'users', component: Users },
    { path: 'createUser', component: CreateUser }
];
@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class UserRoutes { }

在此代码中,我们向 Angular 注册,当用户访问 "<baseUrl>/users" 时,Users 组件将在浏览器上呈现。在这种情况下, baseUrl="https:///" 。

{ path: 'users', component: Users },

在浏览器上,内容呈现如下照片

我想让应用程序在用户浏览到 "https://" 时重定向到 "https:///users",我可以这样做吗?

是的,我们可以。请将此路由配置添加到路由配置列表。

{ path: "", redirectTo: "/users", pathMatch: 'full' }

userRoute.ts 将是

let routes: Routes = [
    { path: "", redirectTo: "/users", pathMatch: 'full' },
    { path: 'createUser', component: CreateUser },
    { path: 'users', component: Users }
    
];
@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class UserRoutes { }

当我运行 "https://" 时,系统会重定向到 "https:///users",然后在刷新浏览器时,我得到 "HTTP 错误 404.0 - 未找到",我的应用程序已部署在 IIS 上?

是的,请帮我检查一下我们是否在应用程序的根文件夹中有一个 "web.config" 文件。缺少此文件将引发此类错误。

为什么我需要 web.config 文件,我没有使用任何服务器代码?

浏览到 "https:///users" 将触发 IIS 上的默认处理程序,并且没有任何内容映射到该 URI。这就是为什么浏览器显示 "HTTP 错误 404.0 - 未找到"的原因。

<rewrite>
	<rules>
		<rule name="Rewrite to default" enabled="true" stopProcessing="true">
			<match url="^[^.]+$" />
			<action type="Rewrite" url="/" />
		</rule>
	</rules>
</rewrite>

Web.Config 中,它将自动将当前请求重写到 "index.html" 文件(IIS 的默认页面),这是 Angular 使用已注册的路由配置处理 "/users" 路径的地方。

从 index.html 文件中删除 <base href="http://www.tranthanhtu.vn/"/> 时,我收到如下错误,这是什么?

这是 HTML 标签,有关更多信息,请参阅 HTML <base> 标签

一般来说,浏览器使用它来标识将加载的资源的位置。

默认情况下,我们使用 <base href="http://www.tranthanhtu.vn/"/>

当我在 "Users" 和 "Add new User" 之间导航时,整个网页似乎被重新加载了?

是的,查看 layout.html,链接到 "Users" 和 "Add new User" 是纯 HTML 属性。

请将它们更改为

现在,让我们再次尝试点击这些链接,页面之间的导航看起来更好了。

我可以将页面内容区域移动到其他位置吗?

layout.html 中,我们可以将 "router-outlet" 标签移动到适当的位置。

浏览器上的内容也将被更改

我是否可以将参数从一个页面传递到另一个页面,我该怎么做?

是的,你可以。让我们在 UserRoutes.ts 中添加一个新的路由配置

{ path: 'editUser/:id', component: CreateUser }

CreateUser 的构造函数中

export class EditUser{
    constructor(route: ActivatedRoute){
        console.log("User selected:", route.params.value.id);
    }
}

ActivatedRoute 的实例将由 Angular 使用依赖注入(或简称 DI)机制传递到 CreateUser 的构造函数中(稍后我们将讨论 DI)。

我们可以通过以下方式获取传递参数的值:route.params["value"].<name of parameter in route config>。例如:route.params["value"].id 将返回所选用户的 id

如何通过我的代码在页面之间导航?

让我们在 users.html 中添加一些 HTML,如下所示

<div>
	<table class="table">
		<thead>
			<tr>
				<th>#</th>
				<th>First Name</th>
				<th>Last Name</th>
				<th>Username</th>
				<th>Action</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<th scope="row">1</th>
				<td>TU</td>
				<td>Tran</td>
				<td>@tutran</td>
				<td>
					<a (click)="onEditClicked(1)" title="Edit tutran">
                    <i class="fa fa-edit"></i></a>
				</td>
			</tr>
			<tr>
				<th scope="row">2</th>
				<td>TU</td>
				<td>Tran 1</td>
				<td>@tutran1</td>
				<td>
					<a (click)="onEditClicked(2)" title="Edit tutran1">
                    <i class="fa fa-edit"></i></a>
				</td>
			</tr>
			<tr>
				<th scope="row">3</th>
				<td>TU</td>
				<td>Tran 2</td>
				<td>@tutran2</td>
				<td>
					<a (click)="onEditClicked(3)" title="Edit tutran3">
                    <i class="fa fa-edit"></i></a>
				</td>
			</tr>
		</tbody>
	</table>
</div>

Users 类中,我们添加 "onEditClicked" 处理程序,如下所示

import { Component } from "@angular/core";
import { Router } from "@angular/router";
@Component({
    selector: "users",
    templateUrl: "src/users.html"
})
export class Users {
    private router: Router;
    constructor(router: Router) {
        this.router = router;
    }
    public onEditClicked(userId: string) {
        this.router.navigate(["/editUser", userId])
    }
}

在代码中,我们使用 router.navigate 函数导航到 "editUser" 页面

 this.router.navigate(["/editUser", userId])

基于 userRoutes.ts 中的路由配置

{ path: 'editUser/:id', component: EditUser }

如果我有多个参数,我可以做什么?

我们注册路由配置

{ path: 'editUser/:id1/:id2', component: EditUser }

并使用 router.navigate 函数导航,如下所示

this.router.navigate(["/editUser", "value-of-id1", "value-of-id2"])

我可以在路由配置中指定可选参数吗?

目前不行,所有参数都是必需的。我们可以定义具有不同参数的多个路由,如下所示
let routes: Routes = [
    { path: "", redirectTo: "/users", pathMatch: 'full' },
    { path: 'addNewUser', component: CreateUser },
    { path: 'editUser/:id', component: EditUser },
    { path: 'editUser/:id1/:id2', component: EditUser },
    { path: 'users', component: Users }
];

使用具有不同参数的多个路由会创建重复的路由配置,有其他解决方案吗?

我完全同意,这会导致许多类似的路由配置,并引发与维护相关的其他问题。

对于可选参数,我们应该将它们作为查询参数传递。这是正确的使用方法。

例如,在我们的例子中,id 是一个必需参数,而 id1 是可选参数。我们只需要为此注册路由配置,如下所示

{ path: 'editUser/:id', component: EditUser }

userRoutes.ts 将是

let routes: Routes = [
    { path: "", redirectTo: "/users", pathMatch: 'full' },
    { path: 'addNewUser', component: CreateUser },
    { path: 'editUser/:id', component: EditUser },
    { path: 'users', component: Users }
];

Users.ts 中,我们导航到 "编辑用户" 页面

public onEditClicked(userId: string) {
	this.router.navigate(["/editUser", userId,{id1:"optional-parameter"}])
}

注意:查询参数作为 JSON 对象传递。

EditUser.ts 中,我们取回这些值并打印到控制台

export class EditUser{
    constructor(route: ActivatedRoute){
        let requiredIdparam=route.params["value"].id;
        let optionalIdparam=route.params["value"].id1;
        console.log("User selected:", requiredIdparam, optionalIdparam);
    }
}

浏览器中的结果如下所示

感谢您的阅读!

历史

  • 2017 年 1 月 14 日:初始版本

© . All rights reserved.