一、前言
前一段時間做項目時,遇到一個問題就是AngularJS實現圖片預覽和上傳的功能,當時查閱文檔(都是英文文檔)折騰了很久才弄出來,現將整個流程整理出來,有需要的朋友可以參考一下,如果您有更好的方法,歡迎留言交流~~話不多說直接看實現。
二、具體實現
1、html標簽結構
<input type="file" file-model="myFile"/>
<div class="col-md-12">
<img ng-src="{{imageSrc}}" />
</div>
input文件上傳標簽,div包裹的img標簽為圖片預覽區域
2、定義directive
angular.module('app')
.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs, ngModel) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(event){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
//附件預覽
scope.file = (event.srcElement || event.target).files[0];
scope.getFile();
});
}
};
}]);
input標簽中的屬性file-model即就是Angular中的指令,在上面代碼的link方法中,我們為指令file-model所在的元素綁定了change事件,change方法中獲取到要上傳的文件對象,並調用了controller中的getFile()方法(詳見controller)
3、定義控制器UploaderControler
angular.module('app')
.controller('UploaderController', function($scope, fileReader){
$scope.getFile = function () {
fileReader.readAsDataUrl($scope.file, $scope)
.then(function(result) {
$scope.imageSrc = result;
});
};
})
控制器中定義了一個UploaderController,該控制器在其作用域中定義了getFile()方法,getFile方法中調用了fileReader service中的readAsDataUrl方法,此方法中生成了圖片的地址url,並將結果返回getFile中,將返回的url賦值給$scope.imageSrc ,根據Angular雙向數據綁定的機制,img元素中ng-src屬性值為url,那麼就可以在頁面上預覽圖片了。fileReader service是如何定義的呢?
4、定義service fileReader
angular.module('app')
.factory('fileReader', ["$q", "$log", function($q, $log){
var onLoad = function(reader, deferred, scope) {
return function () {
scope.$apply(function () {
deferred.resolve(reader.result);
});
};
};
var onError = function (reader, deferred, scope) {
return function () {
scope.$apply(function () {
deferred.reject(reader.result);
});
};
};
var getReader = function(deferred, scope) {
var reader = new FileReader();
reader.onload = onLoad(reader, deferred, scope);
reader.onerror = onError(reader, deferred, scope);
return reader;
};
var readAsDataURL = function (file, scope) {
var deferred = $q.defer();
var reader = getReader(deferred, scope);
reader.readAsDataURL(file);
return deferred.promise;
};
return {
readAsDataUrl: readAsDataURL
};
}])
fileReader service主要是完成生成獲取到的文件的url地址,返回到view進行預覽。
5、附件上傳的實現
附件上傳主要是將頁面表單數據通過後台提供的接口寫入到數據庫中,具體實現在控制器UploaderControler中增加如下代碼:
// 組裝表單數據
var postData = {
vacationType: $scope.leave.type,
reason: $scope.leave.reason,
familyRelation: +$scope.leave.type == 7 ? $scope.leave.relation : "",
startTime: startTime,
endTime: endTime,
fileName: $scope.imageSrc,
workDelivers: workDelivers,
ccmailNickNames: sendPersons,
realDays: +$scope.leave.type == 8 ? $scope.leave.timeLong : ""
};
var promise = postMultipart('/maldives/leave/save', postData);
function postMultipart(url, data) {
var fd = new FormData();
angular.forEach(data, function(val, key) {
fd.append(key, val);
});
var args = {
method: 'POST',
url: url,
data: fd,
headers: {'Content-Type': undefined},
transformRequest: angular.identity
};
return $http(args);
}
postData為表單中的數據(包括上傳的圖片信息),'/maldives/leave/save'表示的是請求後台的數據接口,$http是Angular內置的service,能向後台發送GET或POST請求。
三、對Angular中service、controller、directive的認識和理解
Service就是單例對象在AngluarJS 中的一個別名。這些單例對象會被經常傳來傳去,保證你每次訪問到的都是同一個實例。基於這種思想,單例對象讓我們可以實現一些相當酷的功能,它可以讓很多controller和directive訪問其內部的數值。
controller把service、依賴關系、以及其它對象串聯到一起,然後通過scope把它們關聯到view上。如果在你的視圖裡面需要處理復雜的業務邏輯,那麼把它們放到controller裡面也是一個非常不錯的選擇。
Angular對directive的定義是一段代碼片段,���可以用它來操作DOM,也可以使用它來進行用戶交互。
一些AngularJS相關文章鏈接:
AngularJS權威教程 清晰PDF版 http://www.linuxidc.com/Linux/2015-01/111429.htm
希望你喜歡,並分享我的工作~帶你走近AngularJS系列:
如何在 AngularJS 中對控制器進行單元測試 http://www.linuxidc.com/Linux/2013-12/94166.htm
在 AngularJS 應用中通過 JSON 文件來設置狀態 http://www.linuxidc.com/Linux/2014-07/104083.htm
AngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htm
AngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交數據 http://www.linuxidc.com/Linux/2014-07/104402.htm
AngularJS 的詳細介紹:請點這裡
AngularJS 的下載地址:請點這裡