尝试使用Angular2的路由器

起初/首先/首要一点

我們將在Angular2中嘗試使用路由功能,這在大型SPA中是必不可少的。
我們將使用Angular2的版本為2.0.0-beta.0。

路由器

首先,让我们展示一个最简单的示例。
参考 beta.0 更新的 5 MIN QUICKSTART,我们安排了以下的目录结构。

my-app
├ node_modules
├ app
│ ├ app.component.ts
│ ├ page1.component.ts
│ ├ page2.component.ts
│ └ boot.ts
├ index.html
├ package.json
└ tsconfig.json

以下是index.html的内容。

<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="node_modules/angular2/bundles/router.dev.js"></script>
    <script>
      System.config({
        packages: {
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
        .then(null, console.error.bind(console));
    </script>
    <base href="/">
  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

在5分钟快速入门的index.html中,我们添加了一个script元素和一个base元素来加载router.dev.js。

以下是四个TypeScript文件的内容。

import {Component} from 'angular2/core'

const template = `
<h2>page 1</h2>
`;

@Component({
  template: template
})
export class Page1 {
}
import {Component} from 'angular2/core'

const template = `
<h2>page 2</h2>
`;

@Component({
  template: template
})
export class Page2 {
}

由于页面1和页面2不直接引用模板,因此可以省略选择器。

import {Component} from 'angular2/core'
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'
import {Page1} from './page1.component'
import {Page2} from './page2.component'

const template = `
<router-outlet></router-outlet>
`;

@Component({
  selector: 'my-app',
  template: template,
  directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
  {
    useAsDefault: true,
    path: '/page1',
    component: Page1
  },
  {
    path: '/page2',
    component: Page2
  }
])
export class AppComponent {
}
import {bootstrap} from 'angular2/platform/browser'
import {ROUTER_PROVIDERS} from 'angular2/router'
import {AppComponent} from './app.component'

bootstrap(AppComponent, [
  ROUTER_PROVIDERS
]);

打开浏览器,应该会跳转到http://localhost:3000/page1并显示“page 1”。输入URL并跳转到http://localhost:3000/page2时,显示内容应该会变成“page 2”。

暂且重要的是app.component.ts的@RouteConfig。
该参数需要传入一个Route数组。

在Route的参数中,必须要有path和component。path是URL中反映的路径名称,component是与此Route对应的组件。

通过在前往Page1的Route中添加useAsDefault: true,当访问http://localhost:3000/时,会自动跳转到http://localhost:3000/page1。

Page1和Page2的内容会显示在模板的位置上。
使用需要从angular/router导入ROUTER_DIRECTIVES。

路由链接

嗯,如果保持原样,就必须手动输入URL才能进行页面跳转,这样很不方便。
我们尝试使用routerLink来创建到路由的链接。

import {Component} from 'angular2/core'
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'
import {Page1} from './page1.component'
import {Page2} from './page2.component'

const template = `
<a [routerLink]="['Spam']">page1</a>
<a [routerLink]="['Ham']">page2</a>
<router-outlet></router-outlet>
`;

@Component({
  selector: 'my-app',
  template: template,
  directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
  {
    useAsDefault: true,
    path: '/page1',
    component: Page1,
    name: 'Spam'
  },
  {
    path: '/page2',
    component: Page2,
    name: 'Ham'
  }
])
export class AppComponent {
}

修改点有两处。
首先,在Route的参数中添加name。
然后,在template中添加a元素,并在属性中写入[routerLink]=”[‘Spam’]”。
这里的”Spam”对应于Route的name中的”Spam”。

另外,有时候Alpha版的文档中会写成router-link,但实际应该改为routerLink,请注意一下。

导航器导航

在某些情况下,例如提交表单时,我认为您可能希望在Component内先进行处理,然后再进行页面跳转。
以下是一个实现示例。

import {Component} from 'angular2/core'
import {Router} from 'angular2/router'

const template = `
<h2>page 2</h2>
<button (click)="goPage1()">go to page1</button>
`;

@Component({
  template: template
})
export class Page2 {
  constructor(public router: Router) {
  }

  goPage1() {
    console.log('go to page1');
    this.router.navigate(['Spam']);
  }
}

router.navigate的参数似乎与template中的routerLink相同。

定位策略

在Angular2中,可以使用LocationStrategy来设置将Path转换为URL时实际使用https://example.com/page1还是https://example.com/#/page1。
这类似于Angular1中的$locationProvider.html5Mode。
前者称为PathLocationStrategy,后者称为HashLocationStrategy。

默认情况下,PathLocationStrategy是使用的,如果要更改为HashLocationStrategy的示例如下所示。

import {provide} from 'angular2/core'
import {bootstrap} from 'angular2/platform/browser'
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router'
import {AppComponent} from './app.component'

bootstrap(AppComponent, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
]);

生命周期钩子

在Angular2中,通过生命周期钩子可以在组件状态变化的时机插入处理。路由的生命周期钩子有5种类型,分别是OnActivate、OnReuse、OnDeactivate、CanReuse和CanDeactivate。

每个Hook都作为Interface提供,并且在Component中实现Interface的方法。
以下是一个简单的示例。

import {Component} from 'angular2/core'
import {OnActivate, OnReuse, OnDeactivate, CanReuse, CanDeactivate} from 'angular2/router'

const template = `
<h2>page 1</h2>
`;

@Component({
  template: template
})
export class Page1 implements OnActivate, OnReuse, OnDeactivate, CanReuse, CanDeactivate {
  routerOnActivate() {
    console.log('onActivate');
  }

  routerOnReuse() {
    console.log('onReuse');
  }

  routerOnDeactivate() {
    console.log('onDeactivate');
  }

  routerCanReuse() {
    return confirm('can reuse?');
  }

  routerCanDeactivate() {
    return confirm('can deactivate?');
  }
}

在OnActivate的接口中,routerOnActivate方法对应的感觉是这样的。
routerCanReuse和routerCanDeactivate现在返回布尔值或Promise。
虽然我们这次没有尝试,但是通过返回Promise,也可以进行异步处理。

最后

本文中我试用了一些在Angular2的路由器中经常使用的功能。
今年春天我尝试过Angular1的组件路由器,但是在那之后我感觉Angular2的路由器更加精细。

在撰写本文时,非常感谢 @ovrmrw 同学已经为我们编写了使用路由器的示例,给了我们很大的帮助。

    初心者がAngular2で嵌まったり解決したりサンプルコード書いたりしてみた。

请阅读官方文档以了解路由器的详细信息。

    Routing & Navigation
广告
将在 10 秒后关闭
bannerAds