0

ファイルとフォルダーをアップロードする機能を実装しようとしています。いくつかのファイルとフォルダーをクロムにドロップし、タイプ dataTransferItemList のエントリのリストを取得してから、リスト内の各エントリに対して何らかのアクションを実行したいと考えています。webkitGetAsEntry 関数でエントリを取得し、FileEntry オブジェクトのファイル関数を呼び出そうとすると dataTransferItemList が空になります。

_processEntries: function () {
        //this._entries list of entries of type dataTransferItemList
        var entry = this._getNetxFileEntry(this._entries);
        if (!isNullOrUndefined(entry)) {
            if (entry.webkitGetAsEntry) {
                entry = entry.webkitGetAsEntry();
            } else {
                //TODO: code for other browsers without getAsEntry implementation
            }

            if (entry.isFile) {
                this._readAsFileEntry(entry);
            }
            else if (entry.isDirectory) {
                this._readAsDirectoryEntry(entry);
            }
        }
    },

    _readAsFileEntry: function (fileEntry) {
        fileEntry.file($.proxy(this._onFileSuccessfullyRead, this));
    },

    _onFileSuccessfullyRead: function (file) {
        //Here this._entries becomes empty so i can't read next entry
    },

この状況ですべてのエンティティを処理するにはどうすればよいですか? 手伝ってくれてありがとう。

4

1 に答える 1

3

私もこれで頭がいっぱいでした。

私はこの方法で解決しました

afterInit : function() {

    this.uploads = [];

    this.entries = [];
    for ( var i = 0; i < this.options.items.length; i++)
        this.entries.push(this.options.items[i].webkitGetAsEntry());

    this.scan(0);

},

scan : function(i) {

    if (i >= 0 && i < this.entries.length) {

        var entry = this.entries[i];

        if (entry.isDirectory) {
            entry.createReader().readEntries(this.readEntries.bind(this, i + 1));
        } else if (entry.isFile) {
            this.manageFileEntry(entry);
            this.scan(i + 1);
        }

    } else if (this.uploads.length > 0)
        this.doUpload(0);

}

.file() と .readEntries() は非同期であることを思い出してください。これは、メソッドがすぐに戻り、JS エンジンがリソースを「解放」できることを意味します。非同期であるため、dataTransferItemList がスコープ外になり、解放される (null に設定される) 瞬間があります (つまり、メソッドが返されるとき)。

私のコードでわかるように、.file() または .readEntries() への非同期呼び出しのためにアイテムが範囲外になる前に、.webkitGetAsEntry() を呼び出してエントリ参照を予防的に保存します。

これが役に立てば幸いです。解決策を見つける前に、これをデバッグするのに 2 時間かかります。

于 2012-11-18T19:29:26.257 に答える