2013-05-16 64 views
11

我試圖讓角度閱讀文件的內容,用戶通過<input type="file"控件選擇。雖然角度不具有文件上傳控制指令,它應該是很容易解決,與調用$applyHTML5與AngularJS上傳文件

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

不幸的是,該事件從來沒有發射。這就像選擇器無法引用正確的DOM元素:即使選擇器找到元素,文件列表始終爲空。這也會發生,如果我戳穿js控制檯。 DOM檢查器改爲在其屬性中包含文件列表。

這讓我發瘋,但目前爲止它的唯一工作方式是使用分配給全局變量的內聯事件處理程序。爲什麼jquery選擇器返回另一個項目?有一些模板編譯mumbo-jumbo,角度會混淆選擇器嗎?

回答

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

不錯。我最終在控制器中定義了一個全局函數,並從內聯事件處理程序調用它。由於$ scope在外部閉包中,至少我可以$應用更改。該指令絕對是一種更「角度」的方式來做到這一點。但問題是:爲什麼選擇器返回一個'input'元素,看起來與用戶正在進行交互的元素看起來完全一樣,但實際上並不是這樣呢? – BruceBerry

+0

mmmh這不適合我。如果我運行你的plunkr,我總是得到 文件: { 「0」:{} } 我做錯了什麼? – pomarc

+0

@pomarc IIRC,它用於工作......但似乎現代瀏覽器不支持字符串化File對象。您必須直接訪問屬性才能在視圖中顯示它們。 – Tosh

2

如果您正在使用的角度尋找文件上傳你可以使用這個插件

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

它基本上是像夢囈的回答一個指令,需要照顧的非HTML5的瀏覽器與FileAPI閃光燈填充工具,具有$ http.uploadFile函數通過AJAX上傳實際的文件。

1

site使用Angular service進行HTML5文件上傳。一個簡單的方法是設置一個調用服務的控制器,並在異步調用完成時更新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.