主要需求
需要一個上傳檔案的功能,但為了視覺統一,要把真正上傳檔案的部分隱藏,用另一個 input 來呈現上傳檔案的內容。
建立上傳檔案區塊
1 | <div class="uploadFileBlock"> |
- 建立一個上傳檔案的區塊(可以看實際專案需求),裡面個別放了兩個 input。
- 第一個 input 的 type 是 file,主要用來上傳檔案用的。
- 第二個 input 的 type 是 text,是用來呈現上傳檔案的檔名。
- 使用按鈕完成上傳檔案的功能。
完成主要架構後先來進行樣式的處理。
CSS 樣式
因為只會出現一個 input,並且前端介面要給使用者看到的是上傳檔案的檔名結果,所以我把 .uploadInput
使用 display:none
隱藏起來,之後要用 Angular 的範本變數去觸發這個功能。
HTML
1 | <div class="uploadFileBlock"> |
此練習有使用到 Tailwind CSS 作樣式,基本上沒有很困難,可以參考樣式內容。
SCSS
1 | .uploadFileBlock { |
使用範本變數取得 click 事件的值
透過自定義的範本變數可以讓按鈕取得 input 裡面的值。
HTML
1 | <div class="uploadFileBlock"> |
- 在第一個 input 給一個 change 事件以及範本變數,這邊自定義為
#fileUpload
,前面要加井字號,這樣就完成了範本變數的綁定。 - 再來在第二個按鈕上新增 click 事件,去取得範本變數 fileUpload 的 click 方法。
此時 ts 檔也要同時新增 change 事件方法。
TypeScript
1 | fileSelected(e) { |
在點擊按鈕後會彈跳出一個視窗,需要先選擇檔案,可以任意選擇一個檔案試試看,選擇後在 console 就可以看到有事件的內容出現。
然後可以找到一個 target 的屬性,再找到 files 這個屬性,在點開會發現是一個陣列,裡面有一個物件。
取得 file 的內容
此時可以在 fileSelected 方法中寫入功能,這邊假設我要取得檔案的名稱。
TypeScript
1 | fileName: string; |
- 從 console 中可以知道 files 裡面只有一個物件,所以我取得第 0 筆資料。
- 判斷如果 file 是 true 的時候,宣告一個
fileName
去儲存file.name
的檔案名稱。 - 因為來源是不可改變的,所以我用 const 宣告一個變數
formData
,並 new 一個 formData 的實體。 - 在使用
append
方法去增加檔案。
把檔名放到前端顯示
剛剛已經透過全域變數取得 file.name
的字串,我在第二個 input 綁定一個 placeholder,並用三元運算子判斷要顯示變數內容或是預設提示文字。
HTML
1 | <input |
這樣就完成了,
DEMO: https://stackblitz.com/edit/angular-ivy-cfj62u?embed=1&file=src/app/app.component.html