ホームページ  >  記事  >  ウェブフロントエンド  >  Angular4 学習ノートルーターの簡単な使い方

Angular4 学習ノートルーターの簡単な使い方

亚连
亚连オリジナル
2018-05-28 10:55:251081ブラウズ

この記事では主に Angular4 学習ノートルーターの簡単な使い方を紹介します。編集者がそれを参考にさせていただきます。エディターをフォローして一緒に見てみましょう

ルーター、つまりルーティングはフロントエンドにおいて比較的重要な概念です。特定のアドレスと対応するページは、ルータを介して関連付けられ、分離され、分離の目的を達成します。 src/app ディレクトリに新しいdetailフォルダーを作成し、gundam-detail.componentという名前のファイルを作成します。

import { Component } from '@angular/core';
import { Gundam } from '../../model/gundam';
@Component({
  template: `
    <p *ngIf="selectedGundam">
    <span>{{selectedGundam.name}}</span>
    <span>{{selectedGundam.type}}</span>
    </p>
  `
})
export class GundamDetailComponent {
    selectedGundam: Gundam;
}

ps: 命名に関しては、基本的にxxx+"-"+"ビジネスタイプ"+"コンポーネントタイプ"という命名方法が使用されており、少なくとも公式ドキュメントではこれが推奨されています。もちろん、コンポーネントに「Zhutou San」という名前を付けることもできますが、標準的な名前を付けるとコンポーネントの可読性が向上します。たとえランダムなメンテナに名前を付けても構わないとしても、彼らが長期間にわたって同じコード部分をリファクタリングしないとは誰も断言できません。したがって、それでも親切でなければなりません。コメントを書かなくても大丈夫です。名前はもっと統一したほうがいいでしょう。

ps2: サブコントラクトの方法に関しては、ビューとコントローラーをまとめてからロジックに従ってさらに分割することを好む人もいます。最初にロジックを分割してからビューを分割するという逆の方法を行う人もいます。そしてコントローラー。これについては統一した結論はないようですが、個人的には後者の方法が好みなので、このプロジェクトでは後者の方法を採用しています。

現時点ではファイルには何もありません。単に app.component.ts で神殿を移動するだけです。

まず要件を明確にしてから、ルーターの作成を開始します。

必要条件: ガンプラ一覧ページの項目をクリックすると、ガンプラの詳細ページにジャンプします。

Angular コンポーネントとして、ページ内でルーターを使用したい場合は、まず app.module.ts で宣言する必要があります。

追記: 前の業務は app.module.ts とは何の関係もありませんが、これが重要ではないという意味ではありません。 app.module.ts は Android の mainifist ファイルに相当し、プロジェクト全体を調整・管理します。

app.module.ts を開きます:

  1. imports: コンポーネント ページで基本クラスを使用します。

  2. 宣言: 既存のカスタムコンポーネント宣言。

  3. ブートストラップ: Android のメイン起動として理解でき、プロジェクトの開始時にどのコンポーネントが開始されるかがわかります。

ルーターを使用する前にインポートする必要があります:

import { RouterModule }  from &#39;@angular/router&#39;;

RouterModule の forRoot メソッドを呼び出す必要があるため、RouterModule.forRoot はプロジェクトで使用される基本クラスであるため、これを記述する必要があります。輸入品。

 imports: [
  BrowserModule,
  FormsModule,
  RouterModule.forRoot()
 ],

RouterModule.forRoot は 2 つのパラメータを受け入れます。最初のパラメータはジャンプを示すルート配列であり、その用途は常に無視されます。

ルート クラスには、パスとコンポーネントという 2 つの主要な属性が含まれています。パスにアクセスすると、固有のコンポーネントを見つけることができます。

ホームページと詳細ページの 2 つのコンポーネントを含むルート配列を forRoot に追加します。

RouterModule.forRoot([
  {
    path: &#39;&#39;,
    component: AppComponent
  },
  {
    path: &#39;&#39;,
    component: GundamDetailComponent
  }
])

app.module.ts は次のようになります:

import {
NgModule
} from '@angular/core';
import {
BrowserModule
} from '@angular/platform-browser';
import {
FormsModule
} from '@angular/forms';
import { RouterModule }  from &#39;@angular/router&#39;;
import {
AppComponent
} from './component/appcomponent/app.component';
import { GundamDetailComponent } from './component/detail/gundam-detail.component';
@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    RouterModule.forRoot([
      {
        path: '',
        component: AppComponent
      },
      {
        path: '',
        component: GundamDetailComponent
      }
      ])
  ],
  declarations: [
    AppComponent,
    GundamDetailComponent
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

重要なことが 1 つまだ欠けているため、両方のパスはまだ空であり、それが書き込まれてもエラーが報告されます。 :

エラー: 'AppComponent' をロードするプライマリ アウトレットが見つかりません

Angular では、ルーターはラベル router-outlet で使用されます。つまり、ルーターは表示するコンポーネントを決定し、ルーター アウトレットはどのコンポーネントを決定します。どこに表示するか。 pApp.comPonent.ts のテンプレート

<router-outlet></router-outlet>

を追加し、2 つのホームページを表示します:

app.component.ts
これはコンポーネントとページです。まずブートストラップから

app.component.ts

に入り、インターフェイス (つまり、router-outlet の上の部分) をレンダリングします。再度ルーターを探してみたところ、対応するルーターにもコンポーネントがあることが判明したので、再度ロードしました。

そのため、正常に表示するには、ホームページも別途抽出する必要があります。すべてのコンポーネントは

app.component.ts を通じてロードされます。デモ全体の最も外側のコンテナとして、app.component.ts はいくつかの一般的な操作 (通常: バック アクション) を実行できます。

srcの下に新しいホストパッケージを作成し、新しいgundam-host.component.tsファイルを作成します。

基本的にはアプリ全体の移動、outタグの削除、セレクターの削除(当面は使用しません)ができます。

import {
Component
} from &#39;@angular/core&#39;;
import { Gundam } from &#39;../../model/gundam&#39;;
import { GUNDAMS } from &#39;./../../service/data&#39;;
@Component({
  template: `
    <p *ngFor="let gundam of gundams" (click)="onSelected(gundam)">
      <span>
        {{gundam.name}}
      </span>
    </p>
  `
})
export class GundamHostComponent {
  gundam: Gundam = {
    name: &#39;海牛&#39;,
    type: &#39;NewType&#39;
  };
  gundams = GUNDAMS;
  selectedGundam: Gundam; // 定义一个selectedGudam作为展示详情的变量
  onSelected (gundam: Gundam): void {
    this.selectedGundam = gundam; // 通过参数赋值
  }
}

app.component.ts タグのみを保持し、その他はすべて削除します。

app.module.ts

ファイルを変更し、

gundam-host.component.ts

をインポートし、GundamHostComponentをコンポーネント宣言に追加します。

修改route里的path所指向的component,默认进入后显示主页组件:

before

 

after

path的值为”(空字符串)的表示不需要增加子路径。

修改详情页的路径:

{
  path: &#39;detail&#39;,
  component: GundamDetailComponent
}

在主页里增加跳转连接:

点击跳转(路径已改变)

现在点击主页的高达列表的item后,可以跳转到一个空白的详情页。之所以是空白,是因为详情页的值是需要由主页进行传递的。现在主页详情页分家以后,需要通过路由来进行值传递。

传值的方法有很多种,甚至可以传的值也有很多种。
目前我先用最笨的方法:将gundam类转化为一个字符串,将字符串传递到详情页面后再转化为gundam类。

在app.component.ts文件的class里添加函数:

parseGundamToString(gundam: Gundam): string {
  return gundam.name + &#39;&&#39; + gundam.type;
} // 将gundam类转化为固定格式的字符串

修改app.component.ts文件的template,访问gundam路径时转化传递转化过的gundam字符串

<p *ngFor="let gundam of gundams" routerLink="/detail/name=parseGundamToString(gundam)">
  <span>
  {{gundam.name}}
  </span>
</p>

修改详情页的path

{
  path: &#39;detail/:gundam&#39;,
  component: GundamDetailComponent
}

/:gundam 是一个占位符,又是参数说明。表示传递过来的参数属性是gundam。

这样在detail文件中,就可以从url的连接中拿到传递过来的高达字符串。

获得这个字符串的时机,应该是在在detail页面初始化的时候。Angular提供了所谓的的“钩子”(hook),用来标示component的活动周期—其实也就是是类似于Android里onStart或者onCreate一样的方法。

gundam-detail.component.ts的中添加OnInit钩子,或者说接口:

import { Component, OnInit } from &#39;@angular/core&#39;;

在class后面加implements关键词和OnInit来实现该接口:

export class GundamDetailComponent implements OnInit {
  selectedGundam: Gundam ;
  ngOnInit(): void {
  }
}

剩下的事情,就是读取连接上传来的参数就可以了。

读取连接上传递的参数还是要用到router里的几个类,所以需要在detail里导入。

import { ActivatedRoute, Params }  from &#39;@angular/router&#39;;

导入完成后,通过在构造器里注入的方式进行调用:

(有关注入,现在暂时没有说到)

constructor(
private route: ActivatedRoute){}

angular会自动创建ActivatedRoute的实例。

先在ngOnInit里输出看看params是什么

this.route.params.switchMap((params: Params) => console.log(params))

ps:switchMap是angular官方给的拿取url参数的方法,也是需要预先导入才可以使用:

import &#39;rxjs/add/operator/switchMap&#39;;

ps2: 有关箭头函数

(params: Params) => this.gundamStr = params[&#39;gundam&#39;]

是一个箭头函数,等同于

function(params){
  this.gundamStr = params[&#39;gundam&#39;]
}

其中params是switchMap的返回值,返回的即是通过路由连接传递过来的参数所在的类。

ps3: 箭头函数真的是整个ES6里最恶心的东西,之一。

控制台中 输出:

传递过来的参数,是一个gundam类格式化输出的字符串,所以还要在detail里补充一个反格式化字符串到gundam类的函数。

parseStringToGundam(str: string): Gundam {
  const temp = str.split(&#39;&&#39;);
  const tempGundam: Gundam = {
  name: temp[0],
  type: temp[1]
  };
  return tempGundam;
}

最终,获得detail的初始化是这个样子的

ngOnInit(): void {
  this.route.params // 通过注入的方式拿到route里的参数params
  .switchMap((params: Params) => this.gundamStr = params[&#39;gundam&#39;]) // 通过参数拿到gundam字符串并付给detail里的一个临时变量
  .subscribe(() => this.selectedGundam = this.parseStringToGundam(this.gundamStr)); // 通过反格式化函数解析临时变量并返回给作为显示的model
}

移动web页面间传值确实没有什么太好的方法,angular和react都是如此。以前我们的做法是短的参数直接挂连接传走,长的大的或者object的参数就先保存本地,然后第二个页面再从本地读取。

但是像android那样扔一个intent里直接就过去了的方式,确实没有。

回首页:

 

点击一个列表:

 

包结构:

 

总的来说,业务被分开了,结构干净多了。虽然现在还体现不出来,但是写到后来就觉得心花怒放,磨刀不误砍柴工功啊。

作为router,也可以分离的。

目前我的项目里只有2个页面,如果多起来-比如20来个,那么app.module.ts又会变的乱七八糟。

所以要把router也给扔出去。

新建一个文件app-routing.module.ts,然后把footRoot平移过来(带上引用)。

在app-routing.module.ts文件里,也需要ngModul。个人理解ngModul就相当于一个基类指示器,导出class后以便被其他类引用。

import {
NgModule
} from '@angular/core';
import { RouterModule }  from &#39;@angular/router&#39;;
import { GundamDetailComponent } from './component/detail/gundam-detail.component';
import { GundamHostComponent } from './component/host/gundam-host.component';
@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: '',
        component: GundamHostComponent
      },
      {
        path: 'detail/:id',
        component: GundamDetailComponent
      }
    ])
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

然后既然已经有了这个类,可以导入到app.module.ts里使用使得整个文件看起来清爽一些。

import {
NgModule
} from &#39;@angular/core&#39;;
import {
BrowserModule
} from &#39;@angular/platform-browser&#39;;
import {
FormsModule
} from &#39;@angular/forms&#39;;
import {
AppComponent
} from &#39;./component/appcomponent/app.component&#39;;
import { GundamDetailComponent } from &#39;./component/detail/gundam-detail.component&#39;;
import { GundamHostComponent } from &#39;./component/host/gundam-host.component&#39;;
import { AppRoutingModule } from &#39;./app-routing.module&#39;;
@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule // 调用路由
  ],
  declarations: [
    AppComponent,
    GundamDetailComponent,
    GundamHostComponent
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

当然,官方文档又进行了进一步简化。

既然forRoot是一个Route数组,那么数组也可以单独抽出来,当然进一步抽取也可以放到另一个文件里。

import {
NgModule
} from &#39;@angular/core&#39;;
import { RouterModule, Route }  from &#39;@angular/router&#39;;
import { GundamDetailComponent } from &#39;./component/detail/gundam-detail.component&#39;;
import { GundamHostComponent } from &#39;./component/host/gundam-host.component&#39;;
const routes: Route[] = [
  {
    path: &#39;&#39;,
    component: GundamHostComponent
  },
  {
    path: &#39;detail/:gundam&#39;,
    component: GundamDetailComponent
  }
];
@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

我个人比较偷懒,就先抽取到这一步。

现在连主页面和详情页面都被分开了,项目的耦合度又进一步降低。

再接再厉,我们继续把业务逻辑给也分离出来。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

轻量级JS Cookie插件js-cookie的使用方法

vue-cli开发环境实现跨域请求的方法

详解Vue-cli webpack移动端自动化构建rem问题

以上がAngular4 学習ノートルーターの簡単な使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。