File Upload with AngularJS File Upload:
到现在为止。我们已经件讲述了AngularJS的绝大部分内容。包括指令,服务,控制器,资源等等。但是我们也知道只看不实践是不行的。有时我们并不关心Angular是怎样工作的。我们只是想知道怎么才能让它工作。
这本本章中。我们会通过给出完整例子,来说明常见问题。
这些例子包括
1、使用jQuery Datepicker
2、Teams List应用:控制器和过滤器的通讯
3、AngularJS中的文件上传
4、私用socket.io
5、使用服务(Servers)
【使用jQuery Datepicker】
源码在github中可见
我们想这样定义我们的datepicker组件
1
js这样写
代码很简单。我们来看看特殊的部分。
ng-model
绑定选择事件
调用选择事件
【本例的其他部分】
1 var app = angular.module('myApp', ['myApp.directives']);2 app.controller('MainCtrl', function($scope) {3 $scope.myText = 'Not Selected';4 $scope.currentDate = '';5 $scope.updateMyText = function(date) {6 $scope.myText = 'Selected';7 };8 });
HTML部分
1 2 3 4 5AngularJS Datepicker 6 9 1114 15 17 18 19 20 21 25 26 { {myText}} - { {currentDate}}27 28
【团队列表APP:过滤器和控制器的通信】
【AngularJS中的文件上传】
另一个常见的用法师上传文件。虽然我们可以通过input type=file来实现,但是。我们现在将要拓展文件上传解决方案。比较好的一个是BlueImp’s File Upload,他使用jQuery和jQueryUI。它的api非常简单
代码如下
1 angular.module('myApp.directives', []) 2 .directive('fileupload', function() { 3 return { 4 restrict: 'A', 5 scope: { 6 done: '&', 7 progress: '&' 8 }, 9 link: function(scope, element, attrs) {10 var optionsObj = {11 dataType: 'json'12 };13 if (scope.done) {14 optionsObj.done = function() {15 scope.$apply(function() {16 scope.done({e: e, data: data});17 });18 };19 }20 if (scope.progress) {21 optionsObj.progress = function(e, data) {22 scope.$apply(function() {23 scope.progress({e: e, data: data});24 });25 }26 }27 // the above could easily be done in a loop, to cover28 // all API's that Fileupload provides29 element.fileupload(optionsObj);30 }31 };32 });
这些代码是我们能够简单的定义我们的制定。并且制定onDone和onProgress的回调函数。我们使用函数绑定。这样AngularJS一直能正确调用方法和使用正确的变量。
这是因为我们做了独立的作用域声明。它包含了两种绑定:使用是为onprogree另一种是为ondone。HTML部分代码如下
1 angular.module('myApp.directives', []) 2 .directive('datepicker', function() { 3 return { 4 // Enforce the angularJS default of restricting the directive to 5 // attributes only 6 restrict: 'A', 7 // Always use along with an ng-model 8 require: '?ngModel', 9 scope: {10 // This method needs to be defined and11 // passed in to the directive from the view controller12 select: '&' // Bind the select function we refer to the13 // right scope14 },15 link: function(scope, element, attrs, ngModel) {16 if (!ngModel) return;17 var optionsObj = {};18 optionsObj.dateFormat = 'mm/dd/yy';19 var updateModel = function(dateTxt) {20 scope.$apply(function () {21 // Call the internal AngularJS helper to22 // update the two-way binding23 ngModel.$setViewValue(dateTxt);24 });25 };26 optionsObj.onSelect = function(dateTxt, picker) {27 updateModel(dateTxt);28 if (scope.select) {29 scope.$apply(function() {30 scope.select({date: dateTxt});31 });32 }33 };34 ngModel.$render = function() {35 // Use the AngularJS internal 'binding-specific' variable36 element.datepicker('setDate', ngModel.$viewValue || '');37 };38 element.datepicker(optionsObj);39 }40 };41 });
controller如下
1 var app = angular.module('myApp', ['myApp.directives']);2 app.controller('MainCtrl', function($scope) {3 $scope.uploadFinished = function(e, data) {4 console.log('We just finished uploading this baby...');5 };6 });
【与服务器协同与登录】
最后一个例子涵盖了很多内容。大部分与$http资源有关。根据我们的经验。$http服务是AngularJS中核心服务之一。但是他能被拓展去做很多常规web app需求,这包括:
拥有错误处理链
能够处理授权和登录跳转。
不通过JSON与服务器工作
与外部系统通过jSON工作
所以在这个例子中。我们开发一个完整的应用程序骨架,有这些内容:
1、当错误发生时,跳转到一个统一的错误处理页面。
2、拥有一个ErrorService,能够使指令与视图和控制器之间通信。
3、触发事件,只要服务器返回一个401,这个会被根控制器处理,应用程序级别的根控制器
4、更改请求报文头,增加一些关于当前用户的特定验证信息。
我们不会带大家做整个应用程序,这程序很简单。我们重点说相关步骤。这会很省时间。如果你想复习Server和Factories,回到第七章去。如果你想看着怎么用service,看第5章去。
首先我们看一哈Error Service
1 var servicesModule = angular.module('myApp.services', []); 2 servicesModule.factory('errorService', function() { 3 return { 4 errorMessage: null, 5 setError: function(msg) { 6 this.errorMessage = msg; 7 }, 8 clear: function() { 9 this.errorMessage = null;10 }11 };12 });
我们的与Error service独立的错误消息会查找警告消息属性,并且绑定它。并且警告这条消息。
1 // USAGE: 2 angular.module('myApp.directives', []). 3 directive('alertBar', ['$parse', function($parse) { 4 return { 5 restrict: 'A', 6 template: '',11 link: function(scope, elem, attrs) {12 var alertMessageAttr = attrs['alertmessage'];13 scope.errorMessage = null;14 scope.$watch(alertMessageAttr, function(newVal) {15 scope.errorMessage = newVal;16 });17 scope.hideAlert = function() {18 scope.errorMessage = null;19 // Also clear the error message on the bound variable.20 // Do this so that if the same error happens again21 // the alert bar will be shown again next time.22 $parse(alertMessageAttr).assign(scope, null);23 };24 }25 };26 }]);
我们把错误消息加到HTML上。如下
1
我们需要确认ErrorService在errorService控制器中可用,在我们添加上面的HTML之前。这就是说,如果RootController担任产生AlertBar的功能,那么就有
1 app.controller('RootController',2 ['$scope', 'ErrorService', function($scope, ErrorService) {3 $scope.errorService = ErrorService;4 });
这样我们就创建好了一个非常好的显示隐藏警告的框架。下面我们看看我们怎么样处理各种服务器返回给我们的各种状态码,通过使用拦截器
1 servicesModule.config(function ($httpProvider) { 2 $httpProvider.responseInterceptors.push('errorHttpInterceptor'); 3 }); 4 // register the interceptor as a service 5 // intercepts ALL angular ajax HTTP calls 6 servicesModule.factory('errorHttpInterceptor', 7 function ($q, $location, ErrorService, $rootScope) { 8 return function (promise) { 9 return promise.then(function (response) {10 return response;11 }, function (response) {12 if (response.status === 401) {13 $rootScope.$broadcast('event:loginRequired');14 } else if (response.status >= 400 && response.status < 500) {15 ErrorService.setError('Server was unable to find' +16 ' what you were looking for... Sorry!!');17 }18 return $q.reject(response);19 });20 };21 });
现在我们要做的就是
【总结】
至此本书结束。我们毫无保留的尽量全面介绍了AngularJS。我们的目标是使读者能够轻松开发AngularJS程序打下坚实的基础。本书中举了大量实例来解释,并且本书包括大量关于AngularJS的基础知识和一些高级话题