この記事はAngular+Firebaseでチャットアプリを作るのエントリーです。
前記事:AngularのngForでチャットコメントを実装する
次記事:AngularのPipeを使って、日付を変換する
この記事で行うこと
本稿では、AngularのビルトインディレクティブであるngIfとsubmitイベントを使って、前回に引き続きDOMを操作していきます。
(追記:2020/6)現時点(2020年6月)での最新の内容に書き換えています。
実装内容
ngIfで自分のコメントを表示させる
自分と自分以外を判別するフラグをつける
前回、定数として作成したCOMMENTSに、userとinitialというプロパティを追加し、自分のユーザー情報を作成します。
それに合わせて、定義ファイルchat.tsも更新します。
export class User { // Userの定義を追加
uid: number;
name: string;
constructor(uid: number, name: string) {
this.uid = uid;
this.name = name;
}
}
export class Comment { // Commentの定義を変更
user: User;
initial: string;
content: string;
constructor(user: User, content: string) {
this.user = user;
this.initial = user.name.slice(0, 1);
this.content = content;
}
}
import { Component } from '@angular/core';
import { Comment, User } from './class/chat'; // Userを追加
const CURRENT_USER: User = new User(1, 'Tanaka Jiro'); // 自分のUser情報を追加
const ANOTHER_USER: User = new User(2, 'Suzuki Taro'); // 相手のUser情報を追加
const COMMENTS: Comment[] = [ // クラスを元にコメントを作成
new Comment(ANOTHER_USER, 'Suzukiの1つ目のコメントです。'),
new Comment(ANOTHER_USER, 'Suzukiの2つ目のコメントです。'),
new Comment(CURRENT_USER, 'Tanakaの1つ目のコメントです。'),
new Comment(ANOTHER_USER, 'Suzukiの3つ目のコメントです。'),
new Comment(CURRENT_USER, 'Tanakaの2つ目のコメントです。')
];
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public content = '';
public comments = COMMENTS;
public currentUser = CURRENT_USER; // 追加
}
ngIf
で自分のuidを判別し、自分のコメントとして表示させる
ngIf
は、条件式の値がture
の時にDOMを表示させるビルトインディレクティブです。
commentのuidとCURRENT_USERのuidを比較して、値が等しい時は右側に自分のアイコンが出るよう設定します。
<div class="page">
<section class="card">
<div class="card-header">
NgChat
</div>
<div class="card-body">
<ng-container *ngFor="let comment of comments">
<div class="media">
<!--current_user.uidとcomment.user.uidが等しくない場合に表示-->
<div class="media-left" *ngIf="comment.user.uid !== currentUser.uid">
<a href="#" class="icon-rounded">{{comment.initial}}</a>
</div>
<div class="media-body">
<h4 class="media-heading">{{comment.user.name}} Date:2016/09/01</h4>
<div>{{comment.content}}</div>
</div>
<!--current_user.uidとcomment.user.uidが等しい場合に表示-->
<div class="media-right" *ngIf="comment.user.uid === currentUser.uid">
<a href="#" class="icon-rounded">{{comment.initial}}</a>
</div>
</div>
<hr>
</ng-container>
</div>
</section>
<section>
<form class="chart-form">
<div class="input-group">
<input type="text" class="form-control"
[(ngModel)]="content"
name="comment"
placeholder="Comment" />
<div class="input-group-append">
<button class="btn btn-info" type="button">SEND</button>
</div>
</div>
</form>
</section>
</div>
DOMが長くなったことで表示の一部が崩れたので、CSSを修正します。
.page { /*更新*/
max-width: 960px;
height: 100%;
margin: 0 auto;
padding: 10px 0;
background-color: #fff;
border-left: 1px solid #DDDDDD;
border-right: 1px solid #DDDDDD;
box-shadow: 0 0 15px #DDDDDD;
overflow: scroll;
}
.page section{ /*追加*/
margin: 0 10px 30px;
}
.page .page-footer{ /*追加*/
display: block;
position: fixed;
margin: 0;
padding: 10px;
bottom: 0;
height: 55px;
width: 100%;
max-width: 958px;
background-color: #fff;
border-top: 1px solid #DDDDDD;
}
/*削除
.page .chart-form {
margin: 20px 0;
}*/
ディレクティブの
*
と括弧[]``()
*ngIf
のように、ディレクティブの前に*
がついた場合、その=の先にある式はscript文として評価されます。例:*ngIf="comment.user.uid !== current_user.uid"
の場合、それぞれのuidが等しい場合にのみ表示される。
一方、同様に他のディレクティブ 内でもscript文として変数や式を利用したい場合は、[]
や()
を使って表現します。例:[style.color]="comment.user.uid !== current_user.uid ? 'red' : 'black'"
の場合、それぞれのuidが等しい場合にのみ文字色が赤くなる。
submitイベントで新しいコメントを追加する
addComment
関数をAppComponent
に追加する
フォームに入力したコメントをチャットに追加するため、addComment
関数を実装します。
export class AppComponent {
public content = '';
public comments = COMMENTS;
public current_user = CURRENT_USER;
// 新しいコメントを追加
addComment(comment: string) {
if (comment) {
this.comments.push(new Comment(this.current_user, comment));
}
}
submitイベントをHTMLに追加する
Angularは、ビューからデータへ値を渡す時、(click)
や(submit)
のように丸括弧()
をつけて表記します。
(この表記はビューからデータへ、一方向だけに送られるということを意味しています。逆にデータをビューへ渡す時は、角括弧[ ]
を使って表記します。)
ngModel
でcontentを紐付け、入力された値をaddComment関数に渡します。
<section>
<form class="chart-form" (submit)="addComment(content)"><!--addComment()を追加-->
<div class="input-group">
<input type="text" class="form-control"
[(ngModel)]="content"
name="comment"
placeholder="Comment" />
<div class="input-group-append">
<button class="btn btn-info" type="submit">SEND</button><!--submitに変更-->
</div>
</div>
</form>
</section>
実行結果
フォームに「コメント テスト」と入力して、SENDボタンをクリックすると、チャットコメントが追加されました。
ソースコード
この時点でのソースコード