一睬涧、前言
前一段時(shí)間做項(xiàng)目時(shí)蝌诡,遇到一個(gè)問(wèn)題就是AngularJS實(shí)現(xiàn)圖片預(yù)覽和上傳的功能挎春,當(dāng)時(shí)查閱文檔(都是英文文檔)折騰了很久才弄出來(lái)看疙,現(xiàn)將整個(gè)流程整理出來(lái),有需要的朋友可以參考一下直奋,如果您有更好的方法能庆,歡迎留言交流~~話不多說(shuō)直接看實(shí)現(xiàn)。
二脚线、具體實(shí)現(xiàn)
1例驹、html標(biāo)簽結(jié)構(gòu)
<input type="file" file-model="myFile"/>
<div class="col-md-12">
![]({{imageSrc}})
</div>
input文件上傳標(biāo)簽愈诚,div包裹的img標(biāo)簽為圖片預(yù)覽區(qū)域
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]);
});
//附件預(yù)覽
scope.file = (event.srcElement || event.target).files[0];
scope.getFile();
});
}
};
}]);
input標(biāo)簽中的屬性file-model即就是Angular中的指令裳擎,在上面代碼的link方法中,我們?yōu)橹噶頵ile-model所在的元素綁定了change事件斯碌,change方法中獲取到要上傳的文件對(duì)象一死,并調(diào)用了controller中的getFile()方法(詳見(jiàn)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;
});
};
})
控制器中定義了一個(gè)UploaderController傻唾,該控制器在其作用域中定義了getFile()方法投慈,getFile方法中調(diào)用了fileReader service中的readAsDataUrl方法,此方法中生成了圖片的地址url冠骄,并將結(jié)果返回getFile中伪煤,將返回的url賦值給$scope.imageSrc ,根據(jù)Angular雙向數(shù)據(jù)綁定的機(jī)制凛辣,img元素中ng-src屬性值為url抱既,那么就可以在頁(yè)面上預(yù)覽圖片了。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進(jìn)行預(yù)覽蝗敢。
5捷泞、附件上傳的實(shí)現(xiàn)
附件上傳主要是將頁(yè)面表單數(shù)據(jù)通過(guò)后臺(tái)提供的接口寫(xiě)入到數(shù)據(jù)庫(kù)中,具體實(shí)現(xiàn)在控制器UploaderControler中增加如下代碼:
// 組裝表單數(shù)據(jù)
var postData = {
vacationType: $scope.leave.type,
reason: $scope.leave.reason,
familyRelation: +$scope.leave.type == 7 ? $scope.leave.relation : "",
startTime: startTime,
endTime: endTime,
fileName: $scope.myFile,
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為表單中的數(shù)據(jù)(包括上傳的圖片信息)寿谴,'/maldives/leave/save'表示的是請(qǐng)求后臺(tái)的數(shù)據(jù)接口锁右,$http是Angular內(nèi)置的service,能向后臺(tái)發(fā)送GET或POST請(qǐng)求。
三咏瑟、對(duì)Angular中service拂到、controller、directive的認(rèn)識(shí)和理解
Service就是單例對(duì)象在AngluarJS 中的一個(gè)別名码泞。這些單例對(duì)象會(huì)被經(jīng)常傳來(lái)傳去谆焊,保證你每次訪問(wèn)到的都是同一個(gè)實(shí)例∑忠模基于這種思想,單例對(duì)象讓我們可以實(shí)現(xiàn)一些相當(dāng)酷的功能辜王,它可以讓很多controller和directive訪問(wèn)其內(nèi)部的數(shù)值劈狐。
controller把service、依賴關(guān)系呐馆、以及其它對(duì)象串聯(lián)到一起肥缔,然后通過(guò)scope把它們關(guān)聯(lián)到view上。如果在你的視圖里面需要處理復(fù)雜的業(yè)務(wù)邏輯汹来,那么把它們放到controller里面也是一個(gè)非常不錯(cuò)的選擇续膳。
Angular對(duì)directive的定義是一段代碼片段,你可以用它來(lái)操作DOM收班,也可以使用它來(lái)進(jìn)行用戶交互坟岔。
如需轉(zhuǎn)載本文,請(qǐng)注明來(lái)源: http://www.cnblogs.com/changjianqiu/