• angular学习笔记(二十八-附1)-$resource中的资源的方法


    通过$resource获取到的资源,或者是通过$resource实例化的资源,资源本身就拥有了一些方法,$save,$delete,$remove,可以直接调用来保存该资源: 

    比如有一个$resource创建的服务:

    var service = angular.module('myRecipe.service',['ngResource']);
    service.factory('Recipe',['$resource',function($resource){
        return $resource('/recipe/:id',{id:'@id'});
    }]);
    service.factory('loadRecipes',['Recipe','$q',function(Recipe,$q){
        return function(){
            var defer = $q.defer();
            Recipe.query(function(recipes){
                defer.resolve(recipes)
            },function(err){
                defer.reject(err)
            });
            return defer.promise
        }
    }]);
    service.factory('loadRecipe',['Recipe','$q','$route','$routeParams',function(Recipe,$q,$route,$routeParams){
        return function(){
            var defer = $q.defer();
            Recipe.get({id:$route.current.params.recipeId},function(recipe){
                defer.resolve(recipe)
            },function(err){
                defer.reject(err)
            });
            return defer.promise
        }
    }]);

    然后我通过loadRecipe方法获取到了一个recipe,修改了recipe后需要对它进行提交保存,以下两种方式是一样的:

    1. 通过$resource的save方法(第一个参数是请求提,第二个参数是请求完成后的回调)

            Recipe.save($scope.recipe,function(){
                $location.path('/view/'+$scope.recipe.id)
            });

    2. 由于recipe本身就是通过$resource获取的资源,所以它拥有$save方法,$save方法里的函数就是保存成功后的回调.

            $scope.recipe.$save(function(){
                $location.path('/view/'+$scope.recipe.id)
            });

    除了通过loadRecipe获取到的资源,通过$resource实例化的资源也有$save方法:

    比如下面的recipe:

        $scope.recipe = new Recipe({
            ingredients:[{}]
        });
        $scope.save = function(invalid){
            if(invalid){
                return false
            }
            Recipe.save($scope.recipe,function(recipe){
                $location.path('/view/'+recipe.id)
            });
        };

    $resource()中第二个参数{id:'@id'},表示url中的:id 将会使用资源的id属性值,也就是recipe的id属性值.

    还可以通过$resource()第三个参数来给资源自定义方法:

    return $resource('/card/user/:userID/:id',{userID:123,id:'@id'},{charge:{method:'POST',params:{charge:true},isArray:false}})

    来分析一下这里的第三个参数 {charge:{method:'POST',params:{charge:true},isArray:false}}

    1.charge是自定义方法的名字,资源就可以通过$charge()来调用该自定义方法

    2.charge属性值是一个json对象,里面有三个属性:

       method: 该方法的请求方式: 'POST','GET','DELETE','PUT',等,这里的请求方式可以自定义方法,$resource()返回的对象的get,query,save,remove,delete里用到的只有'GET','POST','DELETE'三种请求方式,但是这里自定义的方法,可以使用$http的所以请求方式. 所以,如果要自定义请求方式,也是通过自定义方法来创建的.

       params: 定义请求url后面的参数,这里是{charge:true},就会向url?charge=true发送请求

       isArray: 定义返回的数据的格式是否是数组

    3.charge属性值除了2里说到的三个属性,还有所有$http里所有可配置的项:

       headers:,

       transformRequest:,

       transformResponse:,

       cache:,

       timeout:,

       withCredentials:

    这些项的意思和具体怎么配置,请参考之前将$http的文章,他们是一致的.

    eg:

    HttpREST.factory('cardResource',function($resource){
        return $resource('/card/user/:userID/:id',{userID:123,id:'@id'},{charge:{method:'POST',params:{charge:true},isArray:false}})
    });
    
    HttpREST.factory('httpCard',function($q,cardResource){
        return {
            getById:function(cardID){
                var defer = $q.defer();
                cardResource.get({id:cardID},function(data,headers){
                    defer.resolve(data);
                },function(data,headers){
                    defer.reject(data);
                });
                return defer.promise
            }
        }
    });
    
    $scope.addCharge = function(){
        $scope.card_1.then(function(card){
             card.$charge({amount:100});
        })
    }

    注意,card_1得到的是promise对象,而不是资源本身,要获得实际的资源,要通过它的then方法里的函数的参数来获得.关于这个问题,请查看: 

    http://www.cnblogs.com/liulangmao/p/3907307.html

    $charge里的参数表示url后面的参数,也就是说:

    card.$charge({amount:100}) 向/card/user/123/1?charge=turn&amount=100发送了post请求,请求体就是card

    请求url里的1是因为在$resource()第二个参数中配置了{id:@id},所以就是card的id,

    请求参数是charge=true是因为在$resource()第三个参数中配置了{charge:{params:{charge:true}}
    请求方式是post是因为在$resource()第三个参数中配置了{charge:{method:'POST',params:{charge:true}}}

    请求参数是amount=100是因为在调用card.$charge()的时候传入了参数{amount:100}
    
    

    资源的方法还有一个特性: 在请求完成后,会自动用返回值来填充调用方法的资源,继而更新视图.无需在回调手动处理:

    eg: 

    html:

      <button ng-click="addCharge()">给建设银行的卡充值100元</button>
      <br/>
      <span>{{card_1['name']}}</span>
      <span>{{card_1['amount']}}</span>
      <br/>

    js:

        $scope.addCharge = function(){
            $scope.card_1.then(function(card){
                card.$charge({amount:100});
            })
        }

    node:

    app.post('/card/user/123/:id',function(req,res){
        var index = req.params.id ? req.params.id-1 : cards.length;
        var query = url.parse(req.url,true)['query'];
        if (query.charge){
            cards[index]['amount']+= Number(query['amount'])
        }
        else {
            cards[index] = req.body;
        }
        res.send(cards[index]);
    });

    点击充值后,后台会给建设银行卡添加100元,然后再把建设银行卡这个资源返回给客户端:

    点击按钮后:

    我们可以看到,在card.$charge({amount:100})这个调用中,我们并没有书写回调来改变$scope.card_1,但是视图里card_1['amount']确实发生了变化,原因是,

    angular自动将返回值填充了card,而card是card_1的$$v属性值(关于$$v请查看http://www.cnblogs.com/liulangmao/p/3907307.html),所以视图里的card_1也会被更新.

  • 相关阅读:
    新手安装Oracle数据库指南
    新手IntelliJ IDEA入门指南
    IntelliJ IDEA 开发工具快捷键大全
    打印杨辉三角
    个人作业-Alpha项目测试
    第三次作业
    第二次作业
    第一次作业-林楠-201731062428
    手把手教你实现在Monaco Editor中使用VSCode主题
    一文搞懂jsBridge的运行机制
  • 原文地址:https://www.cnblogs.com/liulangmao/p/3907032.html
Copyright © 2020-2023  润新知