如何使用角度2上传文件?

时间:2016-08-30 11:48:17

标签: angular

我需要使用angular 2上传文件,我在客户端使用它,而我在服务器端使用Web Api。如何使用此组合实现

2 个答案:

答案 0 :(得分:9)

我使用Angular2和ASP.NET Core成功上传了文件。

我意识到你的后端并不完全相同,但我认为它可能会让你朝着正确的方向前进。

我使用了ng2-file-upload from valor-software

使用npm install安装它,将其添加到您的包文件夹,使用systemjs或webpack进行配置。我使用angular-cli webpack,因此我手动执行的唯一配置是在组件文件中。

前端Angular2

import { Component, Input } from '@angular/core';
import { NgClass, NgStyle } from '@angular/common';

import {FILE_UPLOAD_DIRECTIVES, FileUploader, Headers} from 'ng2-file-upload/ng2-file-upload';


const URL = 'http://localhost:49513/api/values/';

@Component({
  selector: '...',
  templateUrl: '...',
  providers: [...],
  directives: [FILE_UPLOAD_DIRECTIVES, NgClass, NgStyle]
})

export class ProjectDetailsComponent {

  public myHeaders: Headers[] = [];


  public uploader:FileUploader = new FileUploader(
  {
      url: URL,
      headers: <Headers[]> [
        { name: 'Content-Type', value: 'multipart/form-data' }
      ]
  });

  public hasBaseDropZoneOver:boolean    = false;
  public hasAnotherDropZoneOver:boolean = false;

  ...

  public fileOverBase(e:any):void {
    this.hasBaseDropZoneOver = e;
  }

  public fileOverAnother(e:any):void {
    this.hasAnotherDropZoneOver = e;
  }

  ...
}

使用ASP.NET Core的后端

[HttpPost]
public async Task<ActionResult> Post(IFormFile file)
{
    try
    {
        if (file != null && file.Length > 0)
        {
            var savePath = Path.Combine(_appEnvironment.WebRootPath, "uploads", file.FileName);

            using (var fileStream = new FileStream(savePath, FileMode.Create))
            {
                await file.CopyToAsync(fileStream);
            }

            return Created(savePath, file)
        }
        return BadRequest();
    }
    catch (Exception)
    {
        return StatusCode(500, ex.Message);
    }

}

奖励:我编辑了他们的html以使用Material2而不是bootstrap。

<div class="container">

      <div class="navbar navbar-default">
          <div class="navbar-header">
              <a class="navbar-brand" href>Angular2 File Upload</a>
          </div>
      </div>

      <div class="row">

          <div class="col-md-3">

              <h3>Select files</h3>

              <div ng2FileDrop
                  [ngClass]="{'nv-file-over': hasBaseDropZoneOver}"
                  (fileOver)="fileOverBase($event)"
                  [uploader]="uploader"
                  class="well my-drop-zone">
                  Base drop zone
              </div>

          </div>

          <div class="col-md-9" style="margin-bottom: 40px">

                <h3>Upload queue</h3>
                <p>Queue length: {{ uploader?.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 uploader.queue">


                        <td><strong>{{ item?.file?.name }} {{item?.progress}} %</strong></td>
                        <td nowrap>{{ (item?.file?.size/1024/1024).toFixed(2) }} MB</td>
                        <td>
                            <div class="progress" style="margin-bottom: 0;">

                                <md-progress-bar mode="determinate" value="{{item.progress}}"></md-progress-bar>

                            </div>
                        </td>


                        <td class="text-center">
                            <span *ngIf="item.isSuccess"><i class="glyphicon glyphicon-ok"></i></span>
                            <span *ngIf="item.isCancel"><i class="glyphicon glyphicon-ban-circle"></i></span>
                            <span *ngIf="item.isError"><i class="glyphicon glyphicon-remove"></i></span>
                        </td>
                        <td nowrap>
                            <button type="button" class="btn btn-success btn-xs"
                                    (click)="item.upload()" [disabled]="item.isReady || item.isUploading || item.isSuccess">
                                <span class="glyphicon glyphicon-upload"></span> Upload
                            </button>
                            <button type="button" class="btn btn-warning btn-xs"
                                    (click)="item.cancel()" [disabled]="!item.isUploading">
                                <span class="glyphicon glyphicon-ban-circle"></span> Cancel
                            </button>
                            <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" style="">
                          <div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': uploader.progress + '%' }"></div>
                      </div>
                  </div>

                  <button (click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length" md-raised-button class="md-raised md-primary">Upload all</button>
                  <button (click)="uploader.cancelAll()" [disabled]="!uploader.isUploading" md-raised-button class="md-raised md-warn">Cancel all</button>
                  <button (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length" md-raised-button class="md-accent md-hue-1">Remove all</button>


              </div>
          </div>
      </div>
  </div>

答案 1 :(得分:1)

对于材料2编辑更多... @Dave感谢您的回答

<style>
    .box.has-advanced-upload {
        background-color: white;
        outline: 2px dashed black;
        outline-offset: -10px;
        height: 100px;
        vertical-align: middle;
        text-align: center;
        line-height: 100px;
    }

        .box.has-advanced-upload .box__dragndrop {
            display: inline;
        }

    .my-drop-zone {
        border: dotted 3px lightgray;
    }

    .nv-file-over {
        border: dotted 3px red;
    }
    /* Default class applied to drop zones on over */
    .another-file-over-class {
        border: dotted 3px green;
    }
</style>
<md-card class="detail-card">
    <md-card-header>
        <md-card-title>
            <h3>Dosya Yükle</h3>
        </md-card-title>
    </md-card-header>
    <md-card-content>
        <div fxLayout="column">
            <div fxLayout="row">
                <div fxLayout="column">
                    <input type="file" ng2FileSelect [uploader]="uploader" multiple /><br />
                    <input type="file" ng2FileSelect [uploader]="uploader" />

                </div>
                <div fxFlex>
                    <h5>Select files</h5>
                    <div ng2FileDrop
                         [ngClass]="{'nv-file-over': hasBaseDropZoneOver}"
                         (fileOver)="fileOverBase($event)"
                         [uploader]="uploader"
                         class="well my-drop-zone box has-advanced-upload">
                        Sürükle bırak
                    </div>
                </div>
            </div>

            <div fxFlex="70" style="margin-bottom: 40px">


                <p>Kuyruk Sayısı: {{ uploader?.queue?.length }}</p>
                <md-grid-list cols="9" rowHeight="30px">
                    <md-grid-tile colspan="3">Dosya</md-grid-tile>
                    <md-grid-tile></md-grid-tile>
                    <md-grid-tile>Boyut</md-grid-tile>
                    <md-grid-tile>İşlem</md-grid-tile>
                    <md-grid-tile colspan="3">Durum</md-grid-tile>
                    <span *ngFor="let item of uploader.queue">
                        <md-grid-tile colspan="3"> <strong>{{ item?.file?.name }}</strong>  </md-grid-tile>
                        <md-grid-tile> <strong> {{item?.progress}} %</strong>  </md-grid-tile>
                        <md-grid-tile>      {{ (item?.file?.size/1024/1024).toFixed(2) }} MB  </md-grid-tile>
                        <md-grid-tile>
                            <span *ngIf="item.isSuccess"><i class="material-icons " style="color: #0ba048;">check</i></span>
                            <span *ngIf="item.isCancel"><i class="material-icons ">cancel</i></span>
                            <span *ngIf="item.isError"><i class="material-icons">error</i></span>
                        </md-grid-tile>
                        <md-grid-tile>
                            <button type="button" class="btn btn-success btn-xs" style="margin-right: 3px;" (click)="item.upload()" [disabled]="item.isReady || item.isUploading || item.isSuccess">
                                <md-icon>cloud_upload</md-icon><span> Yükle</span>
                            </button>
                        </md-grid-tile>
                        <md-grid-tile>
                            <button type="button" class="btn btn-warning btn-xs" style="margin-right: 3px;" (click)="item.cancel()" [disabled]="!item.isUploading">
                                <md-icon>cancel</md-icon><span> İptal</span>
                            </button>
                        </md-grid-tile>
                        <md-grid-tile>
                            <button type="button" class="btn btn-danger btn-xs" style="margin-right: 3px;" (click)="item.remove()">
                                <md-icon>delete_forever</md-icon><span> Sil </span>
                            </button>
                        </md-grid-tile>
                        <md-grid-tile colspan="9">
                            <md-progress-bar mode="determinate" value="{{item.progress}}"></md-progress-bar>
                        </md-grid-tile>
                    </span>
                    <md-grid-tile colspan="9">
                        Kuyruk işlem:
                    </md-grid-tile>
                    <md-grid-tile colspan="9">
                        <md-progress-bar color="primary" mode="determinate" [value]="uploader.progress" style="height:10px"></md-progress-bar>
                    </md-grid-tile>
                </md-grid-list>
            </div>
        </div>

    </md-card-content>
    <md-card-actions>
        <div style="padding:10px">
            <button (click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length" md-raised-button>Tümünü Yükle</button>
            <button (click)="uploader.cancelAll()" [disabled]="!uploader.isUploading" md-raised-button class="md-raised md-warn">Tümünü İptal Et</button>
            <button (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length" md-raised-button class="md-accent md-hue-1">Liste Temizle</button>
        </div>
        <md-progress-bar color="primary" mode="determinate" [value]="uploader.progress" style="height:10px"></md-progress-bar>
    </md-card-actions>
</md-card>