在看AngularJS的一本教材时,某章突然遇到了$q服务的使用。也许是书的编排问题——将成网状互相依赖的模块用线性顺序书写——总之我是始终搞不明白为什么要这么用,用了有什么好处。html
没有后端的前端如同空中楼阁。我用node.js和mongodb搞了一个简单的restful服务,前端用AngularJS。通过一遍遍的排错,最终差很少理解了$q的用法和优势。前端
不使用$qnode
服务mongodb
app.factory('BokanWork', ['$resource', function($resource){ return $resource('api/bokanwork/:id', {}); }]);
控制器,注入服务BokanWork数据库
app.controller('BokanWorkListCntl', ['$scope', 'BokanWork', function($scope, BokanWork){ $scope.bokanWorkList = BokanWork.query(); }]);
显示问题:后端
路由跳转后才进行数据库访问,数据区域会出现短暂空白。api
使用$qpromise
服务restful
注入服务$q和BokanWork,建立promise服务MultiBokanWorkLoader。app
{id: '@_id'}的意思是说,在POST/DELETE等请求时,将对象里的_id字段(mongodb的ObjectId)提取出来,填补在url对应的id里。
顺便一提,Node.JS某本教材上是用PUT请求进行更新……这里我给改为POST咯……
services.factory('BokanWork', ['$resource', function($resource){ return $resource('api/bokanwork/:id', {id: '@_id'}); }]); services.factory('MultiBokanWorkLoader', ['BokanWork', '$q', function(BokanWork, $q){ return function() { var delay = $q.defer(); BokanWork.query(function(works){ delay.resolve(works); }, function(){ delay.reject('Unable to fetch BokanWork lists'); }); return delay.promise; }; }]);
路由配置。
resolve配置在promise解决后要注入的参数bokanWorkList。
when('/bokanwork', { templateUrl: 'tpl/bokanwork_list.html', controller: 'BokanWorkListCntl', resolve: { bokanWorkList: function(MultiBokanWorkLoader) { return MultiBokanWorkLoader(); } } })
控制器,注意参数bokanWorkList,是在路由配置注入的。
controllers.controller('BokanWorkListCntl', ['$scope', 'bokanWorkList', function($scope, bokanWorkList){ $scope.bokanWorkList = bokanWorkList; $scope.remove = function(index){ $scope.bokanWorkList[index].$remove(function(){ $scope.bokanWorkList.splice(index, 1); }); }; }]);
优点:在数据获取以后(即promise resolve以后)才进行路由跳转,数据区域不会空白。