美文网首页
ionic3 filechooser插件 小白踩坑历程

ionic3 filechooser插件 小白踩坑历程

作者: 曾大播 | 来源:发表于2019-02-17 19:55 被阅读0次

    本人是ionic框架的一名小白,之前用ionic3做项目。项目做了一半之后停做了一段时间,现在继续开始。但是发现,ionic已经升级到了ionic4版本,但ionic4跟ionic3差别还挺大的,所以我还是选择用熟悉的ionic3来接着做项目。

    最近,身为小白的我在研究怎么在手机上选择文件并且上传,想到了两个思路,一个是用HTML上的:

    
    <input class='file'></input>
    
    

    这是HTML的经典方法,但是本人用这个方法获取了文件之后就不会怎么上传了。查了一下大佬的文章,知道了ionic框架下有个专门的方法上传,就是用filechooser插件获取文件URL,然后用filetransfer来上传。具体方法参见这位大佬的文档:

    ionic文件上传

    这个文档将过程写的很清楚,但是本人实践的时候,在filechooser这个插件上遇到了极大的难题: 按照官网文档对这个插件的说明:

    File Chooser - Ionic Documentation

    在命令行的项目根目录用

    
    ionic cordova plugin add cordova-plugin-filechooser
    
    npm install @ionic-native/file-chooser
    
    

    然后在正文中用

    import { FileChooser } from '@ionic-native/file-chooser/ngx';
    //别忘了要在providers里面加上FileChooser,后面的FileTransfer同理
    constructor(private fileChooser: FileChooser) { }
    
    ...
    
    this.fileChooser.open()
      .then(uri => console.log(uri))
      .catch(e => console.log(e));
    

    uri就是文件在你手机上的绝对路径,然后借助FileTransfer实现上传,要先插入啊,声明啊什么的跟filechooser是一样的。下面是FileTransfer的相关代码内容:

    options = {
        fileKey: 'file',
        fileName: 'name',
        params: {name: filename, type: filetype, model: 'file', author: global.username},
        headers: {}
    }
    var reqUri = APP_SERVE_URL + '/postimg';    // APP_SERVE_URL是服务器地址
    const fileTransfer: FileTransferObject = this.transfer.create();
    fileTransfer.upload(uri, reqUri, options).then((data) => {
        alert('上传成功');
    }, (err) => {
        alert('上传失败');
    });
    
    

    我照做了,然而我遇到了这样的问题,不知道各位有没有:

    
    Object(...) is not a function
    
    

    发现是filechooser有问题。这个问题,困扰了我好久,难道是filechooser插件的具体内容写错了吗?不可能啊,这可是大神写的啊。我猜应该是版本问题,现在我是ionic3的项目,但是ionic版本是ionic4,出点这个问题很可能是版本的问题。

    后来我了解了一下插件的原理,发现问题出在.

    \node_modules@ionic-native\file-chooser\ngx\index.js中:

    
    import { Plugin, cordova, IonicNativePlugin } from '@ionic-native/core';
    
    ……
    
    FileChooser.prototype.open = function () { return cordova(this, "open", {}, arguments); };
    //就是这里cordova(this, "open", {}, arguments)是object(...),因此报错是这里
    

    首先,这里的cordova是小写的,然而在'@ionic-native/core'中只有Cordova,再有,调试后发现Object(...) is not a function说的的确是这里。于是我就改了一下,然后又发现有好多其他问题……比如:

    
    this.filechooser.open().then() i……s not a function
    
    

    这里说明open函数的格式又有问题。。。

    最后,对比着FileOpener2的index.js文件的内容,奋斗了好久,终于将这个官方实例实现了。奋斗过程很复杂,这里就不吐槽了,最后我改对了。

    我只是改了\node_modules@ionic-native\file-chooser\ngx\index.js这个文件,现在发给各位分享一下,当然,可能有其他问题,各位发现的话记得私聊:

    原来的代码:

    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    import { IonicNativePlugin, cordova } from '@ionic-native/core';
    var FileChooserOriginal = /** @class */ (function (_super) {
        __extends(FileChooserOriginal, _super);
        function FileChooserOriginal() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        FileChooserOriginal.prototype.open = function () { return cordova(this, "open", {}, arguments); };
        FileChooserOriginal.pluginName = "FileChooser";
        FileChooserOriginal.plugin = "cordova-plugin-filechooser";
        FileChooserOriginal.pluginRef = "fileChooser";
        FileChooserOriginal.repo = "https://github.com/ihadeed/cordova-filechooser";
        FileChooserOriginal.platforms = ["Android"];
        return FileChooserOriginal;
    }(IonicNativePlugin));
    var FileChooser = new FileChooserOriginal();
    export { FileChooser };
    
    

    现在改为:

    var __extends = (this && this.__extends) || (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();
    var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    };
    var __metadata = (this && this.__metadata) || function (k, v) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
    };
    import { Injectable } from '@angular/core';
    import { Plugin, Cordova, IonicNativePlugin } from '@ionic-native/core';
    var FileChooser = /** @class */ (function (_super) {
        __extends(FileChooser, _super);
        function FileChooser() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        FileChooser.prototype.open = function () { return Cordova(this, "open", {}, arguments); };
        /*FileChooser.pluginName = "FileChooser";
        FileChooser.plugin = "cordova-plugin-filechooser";
        FileChooser.pluginRef = "fileChooser";
        FileChooser.repo = "https://github.com/ihadeed/cordova-filechooser";
        FileChooser.platforms = ["Android"];*/
        FileChooser.decorators = [
            { type: Injectable },
        ];
        FileChooser.ctorParameters = function () { return []; };
        __decorate([
            Cordova({
                callbackOrder: 'reverse'
            }),
            __metadata("design:type", Function),
            __metadata("design:paramtypes", []),
            __metadata("design:returntype", Promise)
        ], FileChooser.prototype, "open", null); 
        FileChooser = __decorate([
            Plugin({
                pluginName: 'FileChooser',
                plugin: 'cordova-plugin-filechooser',
                pluginRef: 'fileChooser',
                repo: ' https://github.com/ihadeed/cordova-filechooser',
                platforms: ['Android']
            })
        ], FileChooser);
        return FileChooser;
    }(IonicNativePlugin));
    export { FileChooser };
    
    

    将文件替换一下,官方的实例就可以用了。

    实际上,这应该是个版本的问题,但是ionic4跟3的差别好像有点大,我不太想去看,所以就在ionic3里面硬改了,如果有哪个道友跟我一样懒,而且遇到了相同的问题,希望能帮助到大家。

    相关文章

      网友评论

          本文标题:ionic3 filechooser插件 小白踩坑历程

          本文链接:https://www.haomeiwen.com/subject/cbcneqtx.html