質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1302閲覧

Angular5で画像アップロード後に該当箇所の画像を動的に変更したいです。

nerianighthawk

総合スコア544

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2018/03/22 06:48

編集2018/03/22 06:51

前提・実現したいこと

サーバサイド: Spring Boot(フロント側で完結する質問なので関係ないかと思います)
フロントエンド: Angular5
ユーザアイコン機能を実装しています。
ユーザ設定画面にて画像アップロード後に画面のリロードをせずにツールバーに表示されているユーザアイコンを切り替えたいです。
詳細は以下の通りです。ご教授よろしくお願いします。

発生している問題・エラーメッセージ

アイコンのアップロードは完了しており、エラーは出ていません。
アップロードされたファイルはサーバ側のresource\imageフォルダに保存されています。
一方クライアント側では以下のようにimgタグで呼び出しています(authService.userdetail.iconUrlはアイコン取得用のAPIのURL)。

html

1<img [src]="authService.userdetail.iconUrl" class="account_icon" />

また、画面遷移はすべてRouterクラスのnavigateメソッドを使っているため、画面のリロードは行っておらず、ツールバーは全画面共通で固定されています。
この場合、もう一度ログインしなおすか画面をリロードするまでツールバーのアイコンの表示が変わりません。
何か対処方法はあるのでしょうか。

該当のソースコード

以下がツールバーのソースになります。

html

1<mat-toolbar class="toolbar"> 2 <button mat-icon-button class="menu_button" (click)="sidenav.toggle()"> 3 <mat-icon>menu</mat-icon> 4 </button> 5 <img id="logo" src="../assets/image/logo.png" (click)="nav.toTop()"> 6 <button mat-button [matMenuTriggerFor]="menu"> 7 <img *ngIf="!authService.isUserEmpty()" [src]="authService.userdetail.iconUrl" class="account_icon" /> {{ authService.userdetail.lastName + authService.userdetail.firstName }} 8 </button> 9 <mat-menu #menu="matMenu"> 10 <button mat-menu-item (click)="nav.toMySetting()">ユーザ設定</button> 11 <button mat-menu-item (click)="logout()">ログアウト</button> 12 </mat-menu> 13</mat-toolbar>

また、以下は一例ですが、画面遷移は以下の通りです。

typescript

1constructor(private router: Router){} 2 3toTop() { 4 this.router.navigate(["/top"]); 5}

アイコンアップロードについてはユーザ設定画面でダイアログを開いた後、ダイアログでファイル選択後アップロードボタンを押すことで、アイコンをアップロードできます。アップロード後ダイアログは閉じるようになっています。

試したこと

  • 画面遷移の度にモデルUserDetailを取り直す。

モデルにアイコン取得用APIのURLを入れているので、モデルのインスタンスを生成しなおすことで表示も切り替わると考えました。しかし、名前等の入力項目は表示が変わったのですが、アイコンの表示は変わりませんでした。

  • 画像アップロード後にリロードする。

ダイアログを閉じた後、画面をリロードするようにしたのですが、UIがとても変な感じになってしまいました(他ではリロードされないのにそこだけリロードされるので)。綺麗なUIならこの手法でもいいと思っていますので、何かやり方があるならご教授よろしくお願いします。

質問事項のまとめ

質問事項がバラついてしまったので、まとめたいと思います。

  1. 画面のリロードを行わずに画像呼び出しを再度行うことは可能でしょうか。可能でしたら方法が知りたいです。
  2. 画像アップロード時の仕様としてリロードしても違和感のないUIを実現するためにはどのようにすればいいでしょうか。

1が可能であれば方法をご教授ください。不可能であれば2を教えて頂きたく思います。
以上、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

h_daido

2018/03/22 12:39

authService.userdetail.iconUrlの値はアップロード前後で変わりますか?キャッシュされているだけとか?
nerianighthawk

2018/03/22 14:20

authService.userdetail.iconUrlの値自体は変わりません。アップロードはサーバ側で参照する画像を置き換える操作となります。何もしない限りAngularの画面遷移ではキャッシュに残っている画像を使っていると思います。
h_daido

2018/03/23 01:42

我々のサービスも類似環境ですが、authService.userdetail.iconUrlのurlがアップロードのたびに変わるスタイルです。その場合はuserDetailモデルの値を書き換えてあげれば変更されますね。なので、おそらくキャッシュが原因かと思った次第です。なので、1.uthService.userdetail.iconUrlにnullや別urlを一度指定する。2.その後uthService.userdetail.iconUrlに正しい値をセットしなおす。で動けばangularのwatchが正式に稼働して動作するかも。上記でデバッグして動けば対策方法が切り分けできそうです。
nerianighthawk

2018/03/23 02:37

h_daidoさんの方法でうまくいきました。ありがとうございます。ベストアンサーとして選びたいのですが、質問に対する回答として入力してもらうことは可能でしょうか。
guest

回答1

0

ベストアンサー

先ほど追記・修正依頼で記載したものです。

根本的には、img srcにセットされる値が変更されないため、angularのウォッチ式が動かずに変更を検知できておらず、imgの画像を再取得しに行っていないのが原因。となるかと思います。

そこで、追記・修正依頼に記載した策を試みてもらったのですが、これはあくまで原因切り分けのための方法ということで、根本対応としては少しイマイチな気もします。
(理由は、今後対象コードをあなた以外の人がメンテしたときに、「なぜ一度nullをセットしているのか?」がわからないためです)

簡単にググったのですが、下記SOの回答の方がいいかなと思いました。
https://stackoverflow.com/questions/18845298/forcing-a-ng-src-reload

正直こちらも完璧にしっくりくる解決策ではないのですが(回答者の方もあくまで"workaround"といっています)、まだこちらの方がコードから意図が汲み取りやすいと思います。

上記回答を利用する場合には、authService.userdetail.iconUrlで利用するAPI側の人と相談して、影響のないパラメーターをセットしてくださいね。

と、まぁ上記が教科書的な対応と思いますが、私が追記・修正依頼に記載した策でもまぁいいとは思います(ちゃんとコメントに残すのが最低条件ですが)。あとは工数と求める品質とで調整して決めてもらえればと思います。

投稿2018/03/23 03:28

h_daido

総合スコア824

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nerianighthawk

2018/03/23 04:13

丁寧な解答ありがとうございます。 確かに意図がわからないコードはよくないですね。 ひとまずコメントで意図は書くようにし、その上で対応方法を考えていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問