2013-05-16 3 views
11

ユーザーが<input type="file"コントロールで選択したファイルの内容を読み上げようとしています。角度は、ファイルアップロードコントロールのディレクティブを持っていないにもかかわらず、$applyを呼び出してこれを修正するのは簡単でなければなりません:HTML5ファイルをAngularJSでアップロードする

function MyController($scope) { 
    $('#myFile').on('change', function() { 
    var that = this; 
    $scope.$apply(function() { $scope.files = that.files }); 
    }); 
} 

残念ながら、イベントは発生しません。セレクタが正しいDOM要素を参照することができないようです:セレクタが要素を見つけたとしても、ファイルのリストは常に空です。これは、jsコンソールで突っ込んだ場合にも発生します。 DOMインスペクタでは、そのプロパティの中にファイルリストがあります。

これは私を夢中にさせていますが、私がそれまでに動作させる唯一の方法は、グローバル変数に割り当てるインラインイベントハンドラを使用することです。 jqueryセレクターが別の項目を返すのはなぜですか?セレクタを混乱させるような角度のあるテンプレートのコンパイルがありますか?ここで

答えて

14

は、私が何をすべきかです:

http://plnkr.co/edit/JPxSCyrxosVXfZnzEIuS?p=preview

app.directive('filelistBind', function() { 
    return function(scope, elm, attrs) { 
    elm.bind('change', function(evt) { 
     scope.$apply(function() { 
     scope[ attrs.name ] = evt.target.files; 
     console.log(scope[ attrs.name ]); 
     }); 
    }); 
    }; 
}); 

テンプレート:

<input type="file" filelist-bind name="files"/> 
<p>selected files : <pre>{{ files | json }}</pre></p> 

タスクのこの種の、あなたは間違いなくディレクティブを使用するようにしたいです。 しかし、あなたの主な関心事は、選択したファイル オブジェクトにアクセスする方法であり、私の例ではそれを明確にする必要があると思います。あなたは、角度でファイルアップロードを探しているなら

+0

nice。コントローラーでグローバル関数を定義し、それをインラインイベントハンドラーから呼び出すことになりました。 $ scopeは外側のクロージャに入っているので、少なくとも変更を適用できます。この指示文は、それを行うための「角度のある」方法です。しかし、質問は立っています:なぜセレクタは、ユーザが相互作用しているような "input"要素を返しますが、実際にはそうではありませんか? – BruceBerry

+0

mmmhこれは私のためには機能しません。あなたのplunkrを実行すると、私はいつも ファイルを取得します: { "0":{} } 私は間違っていますか? – pomarc

+0

@pomarc IIRC、それは動作するために使用されました...しかし、現代のブラウザはFileオブジェクトの文字列化をサポートしていないようです。プロパティに直接アクセスしてビューに表示する必要があります。 – Tosh

2

あなたは

https://github.com/danialfarid/angular-file-upload

このプラグインを使用することができますそれは基本的にFileAPIフラッシュポリフィルと非HTML5ブラウザの世話をし、$を持っているトッシュの答えのようなディレクティブです実際のファイルをAJAX経由でアップロードするには、http.uploadFile関数を使用します。

1

このsiteは、HTML5ファイルアップロードにAngularサービスを使用しています。簡単な方法は、非同期呼び出しが完了したときにサービスを呼び出し、UIを更新するコントローラをセットアップすることです。

コントローラ:

myapp.controller('fileUploadCtrl', ['$scope', '$q', 'FileInputService', function ($scope, $q, FileInputService) { 
      $scope.fileInputContent = ""; 
      $scope.onFileUpload = function (element) { 
       $scope.$apply(function (scope) { 
        var file = element.files[0]; 
        FileInputService.readFileAsync(file).then(function (fileInputContent) { 
         $scope.fileInputContent = fileInputContent; 
        }); 
       }); 
      }; 
     }]); 

サービス:

myapp.service('FileInputService', function ($q) { 

    this.readFileAsync = function (file) { 
     var deferred = $q.defer(), 
     fileReader = new FileReader(), 
     fileReader.readAsText(file); 

     fileReader.onload = function (e) { 
      deferred.resolve(e.target.result); 
     }; 
     return deferred.promise; 
    }; 
}); 

テンプレート:

Choose File <input type="file" onchange="angular.element(this).scope().onFileUpload(this)"> 
<br /> 
{{fileInputContent}} 

参考:あなたは完全なソースコードを検索し、参照することができon this site.

関連する問題