پیشنیازهای کار با کامپوننت ng2-file-upload
برای شروع به کار با کامپوننت ng2-file-upload، ابتدا نیاز است بستهی npm آنرا نصب کرد:
>npm install ng2-file-upload --save
همچنین یک کامپوننت آزمایشی را هم به برنامه (دقیقا همان مثال مطلب قبلی) جهت اعمال آن اضافه میکنیم:
>ng g c UploadFile/ng2-file-upload-test
پس از آن نیاز است به ماژولی که این کامپوننت جدید در آن قرار دارد، مدخل FileUploadModule کامپوننت ng2-file-upload را افزود:
import { FileUploadModule } from "ng2-file-upload"; @NgModule({ imports: [ FileUploadModule ]
تکمیل Ng2FileUploadTestComponent جهت اعمال ng2-file-upload
اکنون به کلاس کامپوننت جدیدی که ایجاد کردیم، مراجعه کرده و تغییرات ذیل را اعمال میکنیم:
import { FileUploader, FileUploaderOptions } from "ng2-file-upload"; import { Ticket } from "./../ticket"; export class Ng2FileUploadTestComponent implements OnInit { fileUploader: FileUploader; model = new Ticket();
وهله سازی از کامپوننت ng2-file-upload و انجام تنظیمات اولیهی آن
پس از تعریف خاصیت عمومی fileUploader، اکنون نوبت به وهله سازی آن است:
this.fileUploader = new FileUploader( <FileUploaderOptions>{ url: "api/SimpleUpload/SaveTicket", headers: [ { name: "X-XSRF-TOKEN", value: this.getCookie("XSRF-TOKEN") }, { name: "Accept", value: "application/json" } ], isHTML5: true, // allowedMimeType: ["image/jpeg", "image/png", "application/pdf", "application/msword", "application/zip"] allowedFileType: [ "application", "image", "video", "audio", "pdf", "compress", "doc", "xls", "ppt" ], removeAfterUpload: true, autoUpload: false, maxFileSize: 10 * 1024 * 1024 } );
- اگر برنامه از نکات anti-forgery token استفاده میکند، این کامپوننت برخلاف روش مطرح شدهی در مطلب مشابه قبلی، هیچ هدری را به سمت سرور ارسال نمیکند. بنابراین نیاز است کوکی مرتبط را خودمان یافته و سپس به لیست هدرها اضافه کنیم. در اینجا روش استخراج یک کوکی را توسط کدهای جاوا اسکریپتی مشاهده میکنید:
getCookie(name: string): string { const value = "; " + document.cookie; const parts = value.split("; " + name + "="); if (parts.length === 2) { return decodeURIComponent(parts.pop().split(";").shift()); } }
- برای محدود سازی فایلهای ارسالی توسط این کامپوننت، دو روش وجود دارد:
الف) مشخص سازی مقدار خاصیت allowedMimeType
همانطور که مشاهده میکنید، در اینجا باید mime type فایلهای مجاز را مشخص کرد.
ب) مشخص سازی مقدار خاصیت allowedFileType
برخلاف تصور، در اینجا از پسوند فایلها استفاده نمیکند و از یک لیست از پیش مشخص که نمونهای از آنرا در اینجا مشاهده میکنید، کمک گرفته میشود. بنابراین اگر برای مثال تنها نیاز به ارسال تصاویر بود، مقدار image را نگه داشته و مابقی را از لیست حذف کنید.
- removeAfterUpload به این معنا است که آیا لیست نهایی که نمایش داده میشود، پس از آپلود باقی بماند یا خیر؟
- توسط خاصیت maxFileSize میتوان حداکثر اندازهی قابل قبول فایلهای ارسالی را مشخص کرد.
مدیریت رخدادهای کامپوننت ng2-file-upload
اکنون که وهلهای از این کامپوننت ساخته شدهاست، میتوان رخدادهای آنرا نیز مدیریت کرد. برای مثال:
الف) نحوهی ارسال اطلاعات اضافی به همراه یک فایل به سمت سرور
this.fileUploader.onBuildItemForm = (fileItem, form) => { for (const key in this.model) { if (this.model.hasOwnProperty(key)) { form.append(key, this.model[key]); } } };
ب) اطلاع یافتن از رخداد خاتمهی کار
رخداد onCompleteAll پس از ارسال تمام فایلها به سمت سرور فراخوانی میشود:
this.fileUploader.onCompleteAll = () => { // clear the form // this.model = new Ticket(); };
ج) در حین وهله سازی fileUploader، تعدادی محدودیت نیز قابل اعمال هستند. این محدودیتها سبب نمایش هیچگونه پیام خطایی نمیشوند. فقط زمانیکه کاربر فایلی را انتخاب میکند، این فایل در لیست ظاهر نمیشود. اگر علاقمند به مدیریت این وضعیت باشید، میتوان از رخداد onWhenAddingFileFailed استفاده کرد:
this.fileUploader.onWhenAddingFileFailed = (item, filter, options) => { // msg: `You can't select ${item.name} file because of the ${filter.name} filter.` };
د) اگر ارسال فایلی به سمت سرور با شکست مواجه شود، در رخدادگردان onErrorItem میتوان به نام این فایل و اطلاعات بیشتری که از سمت سرور دریافت شدهاست، دسترسی یافت:
this.fileUploader.onErrorItem = (fileItem, response, status, headers) => { // };
ه) اگر از سمت سرور اطلاعات JSON مانندی یا هر اطلاعات دیگری به سمت کلاینت پس از آپلود ارسال میشود، این اطلاعات را میتوان در رخدادگردان onSuccessItem دریافت کرد:
this.fileUploader.onSuccessItem = (item, response, status, headers) => { if (response) { const ticket = JSON.parse(response); console.log(`ticket:`, ticket); } };
ارسال نهایی فرم و فایلها به سمت سرور
در پایان، با فراخوانی متد uploadAll شیء fileUploader جاری، میتوان اطلاعات فرم و تمام فایلهای آنرا به سمت سرور ارسال کرد:
submitForm(form: NgForm) { this.fileUploader.uploadAll(); // NOTE: Upload multiple files in one request -> https://github.com/valor-software/ng2-file-upload/issues/671 }
کدهای کامل کامپوننت ng2-file-upload-test.component.ts را در اینجا میتوانید مشاهده کنید.
تکمیل قالب کامپوننت Ng2FileUploadTestComponent
اکنون که کار تکمیل کامپوننت آزمایشی ارسال فایلها به سمت سرور به پایان رسید، نوبت به تکمیل قالب آن است.
افزودن فیلد اضافی توضیحات به فرم
<div class="container"> <h3>Support Form(ng2-file-upload)</h3> <form #form="ngForm" (submit)="submitForm(form)" novalidate> <div class="form-group" [class.has-error]="description.invalid && description.touched"> <label class="control-label">Description</label> <input #description="ngModel" required type="text" class="form-control" name="description" [(ngModel)]="model.description"> <div *ngIf="description.invalid && description.touched"> <div class="alert alert-danger" *ngIf="description.errors.required"> description is required. </div> </div> </div>
تعریف ویژهی فیلد ارسال فایلها به سمت سرور
<div class="form-group"> <label class="control-label">Screenshot(s)</label> <input required type="file" multiple ng2FileSelect [uploader]="fileUploader" class="form-control" name="screenshot"> </div>
ذکر ویژگی استاندارد multiple را نیز در اینجا مشاهده میکنید. وجود آن سبب خواهد شد تا کاربر بتواند چندین فایل را با هم انتخاب کند. اگر نیازی به ارسال چندین فایل نیست، این ویژگی را حذف کنید.
نمایش لیست فایلها و نمایش درصد پیشرفت آپلود آنها
جدولی را که در تصویر ابتدای بحث مشاهده کردید، به صورت ذیل شکل میگیرد (کدهای آن در همان صفحهی توضیحات کامپوننت نیز موجود هستند):
<div style="margin-bottom: 10px" *ngIf="fileUploader.queue.length"> <h3>Upload queue</h3> <p>Queue length: {{ fileUploader?.queue?.length }}</p> <table class="table"> <thead> <tr> <th width="50%">Name</th> <th>Size</th> <th>Progress</th> <th>Status</th> <th>Actions</th> </tr> </thead> <tbody> <tr *ngFor="let item of fileUploader.queue"> <td><strong>{{ item?.file?.name }}</strong></td> <td nowrap>{{ item?.file?.size/1024/1024 | number:'.2' }} MB</td> <td> <div class="progress" style="margin-bottom: 0;"> <div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': item.progress + '%' }"></div> </div> </td> <td class="text-center"> <span *ngIf="item.isError"><i class="glyphicon glyphicon-remove"></i></span> </td> <td nowrap> <button type="button" class="btn btn-danger btn-xs" (click)="item.remove()"> <span class="glyphicon glyphicon-trash"></span> Remove </button> </td> </tr> </tbody> </table> <div> <div> Queue progress: <div class="progress"> <div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': fileUploader.progress + '%' }"></div> </div> </div> <button type="button" class="btn btn-danger btn-s" (click)="fileUploader.clearQueue()" [disabled]="!fileUploader.queue.length"> <span class="glyphicon glyphicon-trash"></span> Remove all </button> </div> </div>
در اینجا از progress-bar بوت استرپ برای نمایش درصد آپلود فایلها استفاده شدهاست:
<div class="progress" style="margin-bottom: 0;"> <div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': item.progress + '%' }"></div> </div>
غیرفعال کردن دکمهی ارسال، در صورت عدم انتخاب یک فایل
<button class="btn btn-primary" [disabled]="form.invalid || !fileUploader.queue.length" type="submit">Submit</button> </form>
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.