Edited at

【Angular】NgFormを用いて画像のアップロードとPreview表示をする

こんにちは

昨日、画像のアップロードとPreview表示について記事を書きました。

https://qiita.com/TakahitoNakashima/items/354ebd4ceee90bf01696

その部分について、本来はAngularが用意をしている「NgFormを用いるべきだろう」と感じたので、その方法での実装へ変えました。

おそらく、これが一般的なやり方なのではないかと考えています。


ゴール

・無理やり用意した投稿フォームを、NgFormを用いた形へ書き換える


やったこと

・以下2つのページを参考にNgFormへの書き換えを行う

https://angular.jp/guide/forms

https://angular.jp/api/forms/NgForm


詰まったこと

・model.contents , model.fileに値が入らなかった

 → name属性を定義していなかったため。

  以下の2つは必須です。

   ・"ngForm"を読み込ませる

   ・name属性を定義する


以下、before・afterのソースコード

【before】


content-main.component.html

<div class="home-tweet-box tweet-box-component tweet-user">

<input class="tweet-input" [(ngModel)]="newTweetContents" placeholder="いまどうしてる?">
<button (click)="setTweetContents(newTweetContents)">ツイート</button>
<input type='file' accept="image/*" (change)="onChangeInput($event)">
</div>
<img [src]=imageSrc alt="" />


content-main.component.ts

imageSrc = '';

reader = new FileReader();

onChangeInput(evt) {
const file = evt.target.files[0];
this.reader.onload = ((e) => {
this.imageSrc = e.target['result'];
});
this.reader.readAsDataURL(file);
}


【after】


content-main.component.html

<app-tweet-form></app-tweet-form>



tweet-form.component.html

<div class="timeline-tweet-box">

<div class="home-tweet-box tweet-box-component tweet-user">
<form (ngSubmit)="onSubmit()" #tweetForm="ngForm">
<div class="form-group">
<input type='text' class="tweet-input form-control" [(ngModel)]="model.contents" #contents="ngModel" name="contents" placeholder="いまどうしてる?">
<label class='choice-image'>
+
<input type='file' class="form-control" accept="image/*" [ngModel]="model.file" #file="ngModel" name="file" (change)="onChangeInput($event)" style="display:none;">
</label>
<button type='submit' class="tweet-button" (click)="setTweetContents(); tweetForm.reset()">ツイート</button>
</div>
</form>
</div>
<div *ngIf="fileUrl" class="preview-image">
<img [src]=fileUrl alt="" />
</div>
</div>


tweet-form.component.ts

model = new TweetContents(1, '@Taka', '' , '');

reader = new FileReader();
fileUrl = '';
submitted = false;

constructor(private tweetContentsService: TweetContentsService) { }

ngOnInit() {
}

onSubmit() { this.submitted = true; }

setTweetContents(): void {
if (this.model.contents) {
this.tweetContentsService.setTweetContents(this.model.contents, this.fileUrl);
this.prepareNewTweet();
}
}

private prepareNewTweet() {
this.model = new TweetContents(1, '@taka', '', '');
}

onChangeInput(evt) {
const file = evt.target.files[0];
this.reader.onload = ((e) => {
this.fileUrl = e.target['result'];
});
this.reader.readAsDataURL(file);
}



まとめ

きれいになったと思われる。

読んでいただいて、ありがとうございました。