Ionic 2从浏览器

时间:2017-08-17 08:39:37

标签: file ionic-framework file-upload browser ionic2

我有一个Ionic 2 PWA,所以它应该在浏览器中运行。我希望用户可以将文件上传到服务器。因为来自离子原生的文件选择器仅用于android,我不能在浏览器中使用它。所以我的想法是使用type =“file”的输入字段。但我的问题是,我只获取文件名而不是路径。要上传文件,我需要路径。起初我用ngModel尝试了它,然后用离子的表单构建器。这是我使用表单构建器的代码:

TS:

import {Component} from '@angular/core';
import {Validators, FormBuilder, FormGroup } from '@angular/forms';

@Component({
    selector: 'page-test',
    templateUrl: 'test.html',
})
export class TestPage {

    private file : FormGroup;

    constructor( private formBuilder: FormBuilder ) {
        this.file = this.formBuilder.group({
            image: ['']
        });
    }

    logForm(){
        console.log(this.file.value)
    }

}

HTML:

...
<ion-content padding>
    <form [formGroup]="file" (ngSubmit)="logForm()">
        <input type="file" size="50" formControlName="image">
        <button ion-button type="submit">Submit</button>
    </form>
</ion-content>

但就像我说的那样,控制台只记录文件名:

  

对象{image:“2970.jpg”}

如果我记录“this.file”(没有.value),我发现既没有文件对象,也没有这样的东西。有没有办法在离子浏览器应用程序中获取文件路径以将其上传到服务器?

1 个答案:

答案 0 :(得分:2)

我不知道你是否已找到解决方案,但无论如何我都会发布它......

对于此解决方案,您不需要任何外部npm模块。这是一步一步的

运行

创建新组件
$ ionic generate component file-uploader

然后复制并粘贴下面的代码

<强>的src /组件/文件上传/文件uploader.ts

import { Component, ViewChild, ElementRef, Input } from '@angular/core';

import 'rxjs/add/operator/map';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';

/**
 * Usage
 *
 *  <file-uploader [apiUrl]="apiUrl" [params]="uploadParams"></file-uploader>
 *
 *  <file-uploader [apiUrl]="apiUrl" [params]="[{'key':'language_code', 'value': 'en'}]"></file-uploader>
 *
 */

@Component({
selector: 'file-uploader',
templateUrl: 'file-uploader.html'
})
export class FileUploaderComponent
{
    @ViewChild('file') fileInput: ElementRef;

    @Input('apiUrl') apiUrl: string = null;

    @Input('params') params: Array<{key: string, value: string}> = [];

    @Input('buttonText') buttonText: string = 'Upload';

    @Input('buttonType') buttonType: 'button' | 'icon' = 'icon';

    @Input('icon') icon: string = 'cloud-upload';

    @Input('onUploadSuccess') onUploadSuccess: (file: File, response: any) => void
        = function (file: File, response: any) { console.log(file); console.log(response); };

    @Input('onUploadError') onUploadError: (file: File) => void = function (error: any) { console.log(error) };

    fileToUpload: File = null;

    constructor(private httpClient: HttpClient)
    {
    }

    triggerFileInputClick()
    {
        this.fileInput.nativeElement.click();
    }

    onFileInputChange(files: FileList)
    {
        this.fileToUpload = files.item(0);

        if (this.fileInput.nativeElement.value != '')
        {
            this.upload();
        }
    }

    upload()
    {
        const formData: FormData = new FormData();

        formData.append('file', this.fileToUpload, this.fileToUpload.name);

        this.params.map(param => {
            formData.append(param.key, param.value);
        });

        let headers = {};

        this.httpClient
            .post(this.apiUrl, formData, { headers: headers })
            // .map(() => { return true; })
            .subscribe(response => {
                this.onUploadSuccess(this.fileToUpload, response);

                this.fileInput.nativeElement.value = '';
            }, error => {
                this.onUploadError(error);
            });
    }
}

<强>的src /组件/文件上传/文件uploader.html

<div>

    <input type="file" #file (change)="onFileInputChange($event.target.files)">

    <button *ngIf="buttonType == 'button'" ion-button (click)="triggerFileInputClick()">{{buttonText}}</button>

    <ion-icon *ngIf="buttonType == 'icon'" name="cloud-upload" (click)="triggerFileInputClick()"></ion-icon>

</div>

<强>的src /组件/文件上传/文件uploader.scss

file-uploader {
    [type=file] {
        display: none;
    }
}

<强>的src /页/家/ home.html做为

<file-uploader [apiUrl]="apiUrl" [params]="[{'key':'language_code', 'value': languageCode}]"></file-uploader>

您现在需要做的就是在NgModule中加载组件并使用它。

我应该提到的最后一件事是,如果您遇到未定义属性的问题,例如apiUrl,你应该在ngOnInit()方法中初始化它们。

希望有所帮助

<强>更新 不要忘记将文件上传器导入到使用上传器的组件中,否则您将无法绑定到&#39; apiUrl&#39;因为它不是'file-uploader&#39; 错误的已知属性。 我所做的是在components文件夹中创建了新模块components.module.ts文件。然后我将文件上传器组件导入其中。为了使用它,我将组件模块导入到使用文件上传器组件的组件中。

<强>的src /组件/ components.module.ts

import { IonicModule } from 'ionic-angular';
import { NgModule } from '@angular/core';
import { FileUploaderComponent } from './file-uploader/file-uploader';

@NgModule({
    declarations: [
        FileUploaderComponent
    ],
    imports: [
        IonicModule,
    ],
    exports: [
        FileUploaderComponent
    ]
})
export class ComponentsModule {}

<强>的src /页/家/ home.module.ts

import { ComponentsModule } from '../../components/components.module';