SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

進化した「ASP.NET Core 2.0」新しいWeb開発手法を学ぶ

Entity Framework Core 2.0の新機能を使おう

進化した「ASP.NET Core 2.0」新しいWeb開発手法を学ぶ 第6回


  • X ポスト
  • このエントリーをはてなブックマークに追加

画面の実装(1)

 続いてコントローラーを呼び出すクライアントサイドの実装をしていきます。

ブログ一覧画面

 ブログの一覧画面はサイドメニューから遷移して表示される画面とします。そのため初期状態ではすべてのブログを一覧表示し、画面上部に設けた検索フォームから作者名での絞り込み検索ができるようにします。

リスト3 ブログ一覧画面の作成(blog.component.html)
<h1>ブログ一覧</h1>

<!-- 作者名による絞り込み検索用フォーム -->
<form>
    <label for="author">作者:</label>
    <input id="author" name="author" type="text" #author />
    <button (click)="searchByAuthor(author.value)">検索</button>
</form>

<!-- 検索結果を一覧表示するテーブル -->
<table class="table" *ngIf="blogs">
    <thead>
    <tr>
        <th>ID</th>
        <th>Blog title</th>
        <th>Author</th>
    </tr>
    </thead>
    <tbody>
    <tr *ngFor="let blog of blogs" (click)="searchPostById(blog.blog_id)">
        <td>{{ blog.blog_id }}</td>
        <td>{{ blog.blog_title }}</td>
        <td>{{ blog.author }}</td>
    </tr>
    </tbody>
</table>

 続いて、この画面に対応するAngularのコンポーネントを実装していきます。

Blogコンポーネント

 BlogコンポーネントはBlogコントローラーのメソッドにHttp経由でアクセス(検索を実行)し、取得した検索結果データをブログ一覧画面に渡す役割を持ちます。

リスト4 Blogコンポーネントの作成(blog.component.ts)
import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { Router } from "@angular/router";

@Component({
    selector: 'blog',
    templateUrl: './blog.component.html'
})
export class BlogComponent {
    // ブログ一覧画面が参照するフィールド
    public blogs: string[];

    // コンストラクタでブログの一覧を取得する ・・・(1)
    constructor(private http: Http, private router: Router, @Inject('BASE_URL') private baseUrl: string) {
        // BlogコントローラーのBlogsメソッドにアクセスする
        this.http.get(this.baseUrl + 'api/blog/blogs').subscribe(result => {
            this.blogs = result.json() as string[];
        }, error => console.error(error));
    }

    // 選択したブログの記事一覧ページへ遷移する ・・・(2)
    searchPostById(id: string) {
        this.router.navigate(['/post'], {queryParams: {id: id}});
    }

    // 作者名でブログを検索する ・・・(3)
    searchByAuthor(author: string) {
        // BlogコントローラーのFindByAuthorメソッドにアクセスする
        this.http.get(this.baseUrl + 'api/blog/findByAuthor?author=' + author).subscribe(result => {
            this.blogs = result.json() as string[];
        }, error => console.error(error));
    }
}

 ブログ一覧画面を表示する際、最初に呼び出されるのがコンストラクタです(1)。コンストラクタ内ではHttpコンポーネントを使い、BlogコントローラーのBlogsメソッドを呼び出しています。

 Blogsメソッドからレスポンスされたブログの一覧をstring型の配列にキャストし、画面から参照できるフィールド(this.blogs)にセットします。また、ブログ一覧からあるブログを選択した際に記事一覧画面に遷移するためのイベントハンドラーメソッドを用意します(2)。ここではAngularのRouterコンポーネントを使って遷移先画面のパスと、遷移先画面に連携したいデータを渡しています。

 searchByAuthorメソッド(3)は、検索フォームの検索ボタンに対応するメソッドです。ユーザーから入力された作者名をURLパラメータに付与してBlogコントローラーのFindByAuthorメソッドを呼び出しています。

記事一覧画面

 記事一覧画面は、ブログ一覧画面とほぼ同じ実装になります。

リスト5 記事一覧画面の作成(post.component.html)
<h1>記事一覧</h1>

<!-- 記事のタイトルによる前方一致検索用フォーム -->
<form>
    <label for="title">タイトル(前方一致):</label>
    <input id="title" name="タイトル" type="text" #title />
    <button (click)="searchByTitle(title.value)">検索</button>
</form>

<!-- 検索結果を一覧表示するテーブル -->
<table class="table" *ngIf="posts">
    <thead>
    <tr>
        <th>ID</th>
        <th>Post title</th>
    </tr>
    </thead>
    <tbody>
    <tr *ngFor="let post of posts">
        <td>{{ post.post_id }}</td>
        <td>{{ post.post_title }}</td>
    </tr>
    </tbody>
</table>

 このページに対応対応するコンポーネントも作成します。

Postコンポーネント

 Postコンポーネントは、記事一覧画面に対応したコンポーネントで、役割はBlogコンポーネントと同様となります。

リスト6 Postコンポーネントの作成(post.component.ts)
import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';
import { ActivatedRoute } from "@angular/router";

@Component({
    selector: 'post',
    templateUrl: './post.component.html'
})
export class PostComponent {
    public posts: string[];

    // コンストラクタでブログに含まれる記事一覧を取得
    constructor(private http: Http, private route: ActivatedRoute, @Inject('BASE_URL') private baseUrl: string) {
        const blogId = this.route.snapshot.queryParamMap.get('id'); ・・・(1)
        this.http.get(this.baseUrl + 'api/post/posts?blogId=' + blogId).subscribe(result => {
            this.posts = result.json() as string[];
        }, error => console.error(error));
    }

    // タイトル名で記事を検索する
    searchByTitle(title: string) {
        this.http.get(this.baseUrl + 'api/post/findByTitle?title=' + title).subscribe(result => {
            this.posts = result.json() as string[];
        }, error => console.error(error));
    }
}

 Postコンポーネントも、コンストラクタでPostコントローラーを呼び出して記事一覧を取得しています。ただし、記事一覧画面はブログ一覧画面で選択したブログの記事のみを表示する必要があるため、BlogコンポーネントのsearchPostByIdメソッドでRouterコンポーネントにセットしたデータを取り出してURLパラメータとして使用しています(1)。

ナビゲーション・Angularモジュールの修正

 画面の左側に表示されるナビゲーションメニューに、ブログ一覧画面へのリンクを追加します。

リスト7 ナビゲーションメニューへのブログ一覧画面リンクの追加(navmenu.component.html)
・・・中略
<li [routerLinkActive]="['link-active']">
    <a [routerLink]="['/blog']">
        <span class='glyphicon glyphicon-th-list'></span> Blogs
    </a>
</li>

Angularのモジュールの設定

 クライアント側実装の最後に、ここまでで作成したコンポーネントをモジュールに設定していきます。

リスト8 モジュールへのコンポーネントの追加(app.module.shared.ts)
・・・中略
import { BlogComponent } from "./components/blog/blog.component"; // 追加
import { PostComponent } from "./components/post/post.component"; // 追加

@NgModule({
    declarations: [
        ・・・中略
        HomeComponent, // カンマを追加
        BlogComponent, // 追加
        PostComponent // 追加
    ],
    imports: [
        ・・・中略
        RouterModule.forRoot([
            ・・・中略
            { path: '**', redirectTo: 'home' }, // カンマを追加
            { path: 'blog', component: BlogComponent }, // 追加
            { path: 'post', component: PostComponent } // 追加
        ])
    ]
})

 Blog・Postコンポーネントをインポートし、declarationsのリストに追加することでコンポーネントの利用宣言をします。またimports内のRouterModule.forRootメソッドのリストにコンポーネントと対応するパスを記述することで、Routerコンポーネントによる画面遷移が可能となります。

次のページ
画面の実装(2)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
進化した「ASP.NET Core 2.0」新しいWeb開発手法を学ぶ連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 秋葉 龍一(アキバ リュウイチ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10789 2018/04/25 19:43

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング