Angularjs - 定制$资源 [英] Angularjs - customizing $resource

查看:199
本文介绍了Angularjs - 定制$资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用角 $资源为REST服务。由于我的GET响应的怪癖,我不能为CRUD应用程序使用$资源服务。

创建一个新的对象的工作(对于卡),smilar为:

  VAR NEWCARD =新的信用卡式();
newCard.name =迈克·史密斯
。NEWCARD $保存();

获取也可以工作:

  VAR卡=信用卡式()得到({_ ID:1)。

不过,获得响应是不是对象本身,而是其他的消息,它(包装对象)

  {消息:.....
  回应://卡对象
}

因此​​,当我保存通过资源中检索到的情况下,它发出的包装对象(与改性Card对象响应字段)。
这可能是正确的,但我的服务器预计Card对象不是包装。
有没有一种方法来定制$资源,使其发送所需的对象。从文档,貌似只有URL参数是可以改变的。

  $资源(URL [,paramDefaults] [,行动]);


解决方案

我也有与$资源模块中的标准执行中的问题。有一段时间,我只是在$资源文件我自己的本地副本所做的编辑,但我发现,我还是不满意,他们实现的REST资源的方式。我需要的不是被提供了更大的灵活性。

标准 $资源模块只是一个工厂周围的包装$ HTTP。如果您在$资源模块中归结的code可以相当容易地创建你自己定制的实现。

  VAR应用= angular.module('应用',[]);app.factory(信用卡式',['$ HTTP',函数($ HTTP){    功能CreditCardFactory(){        功能parseMessage(消息){
            如果(message.response){
                返回message.response;
            }
        }        功能信用卡式(值){
            angular.copy(价值|| {},这一点);
        }        信用卡式。$ GET =功能(ID){
            VAR值=本的in​​stanceof信用卡式?这种新的信用卡式();
            $ HTTP({
                方法:GET,
                网址:'/ creditcards /+ ID
            })。然后(功能(响应){
                VAR数据= response.data;
                如果(数据){
                    angular.copy(parseMessage(数据),价值);
                }
            });
            返回值;
        };        CreditCard.prototype。$ GET =功能(ID){
            信用卡式$ get.call(本,身份证)。
        };        返回信用卡式;    }    返回CreditCardFactory;}]);

然后,你的控制器函数中,注入信用卡式工厂就像你$资源。

  app.controller('CreditCardCtrl',函数($范围,信用卡式){
    $ scope.creditCard =信用卡式()得到(3)。
});

这允许您解析反正你想要你的休息行动的回应,也可以让你实现你想要的任何操作。比如:我想在我的资源保存方法,将检查是否对象选择使用POST(创建时没有ID可用的新资源)或PUT之前有一个id属性(当更新现有资源有效身份证可用)。

这也将让你实现的处理的 JSON CSRF漏洞。该angular.js方式内置到$ HTTP,但我公司的REST API修复了这个问题,通过在虚拟对象包装JSON阵列。我使用自定义的资源像一块上面来解析虚拟对象了。

I use Angular $resource for REST service. Due to the quirk in my get response, I cannot use $resource service for CRUD application.

Creating a new object work (say for Card), smilar to:

var newCard = new CreditCard();
newCard.name = "Mike Smith";
newCard.$save();

Get also works:

var card = CreditCard().get({_id:1)

But, the GET response is not the object Card itself, but other message with it (wrapper object)

{ message: ".....",
  response: Card //object
}

so when I save the instance retrieved through resource, it sends the wrapper object (with the modified Card object in response field). This probably correct, but my server expect Card object not the wrapper. Is there a way to customize $resource so that it sends the desired object. From the doc, looks like only url parameters can be changed.

$resource(url[, paramDefaults][, actions]);

解决方案

I've also had problems with the standard implementation in the $resource module. For a while I just made edits in my own local copy of the $resource file, but I found that I still was unhappy with the way they implemented REST resources. I needed more flexibility than was offered.

The standard $resource module is just a factory wrapper around $http. If you boil down the code in the $resource module you can create your own custom implementation fairly easily.

var app = angular.module('app', []);

app.factory('CreditCard', ['$http', function($http) {

    function CreditCardFactory() {

        function parseMessage(message) {
            if (message.response) {
                return message.response;
            }
        }

        function CreditCard(value) {
            angular.copy(value || {}, this);
        }

        CreditCard.$get = function(id) {
            var value = this instanceof CreditCard ? this : new CreditCard();
            $http({
                method: 'GET',
                url: '/creditcards/' + id
            }).then(function(response) {
                var data = response.data;
                if (data) {
                    angular.copy(parseMessage(data), value);
                }
            });
            return value;
        };

        CreditCard.prototype.$get = function(id) {
            CreditCard.$get.call(this, id);
        };

        return CreditCard;

    }

    return CreditCardFactory;

}]);

Then, within your controller function, inject the CreditCard factory just as you would $resource.

app.controller('CreditCardCtrl', function($scope, CreditCard) {
    $scope.creditCard = CreditCard().get(3);
});

This allows you to parse the responses of your REST actions anyway you want and also allows you to implement any actions you want. For instance: I wanted a save method on my resources that would check to see if the object had an id property before choosing to use a POST (creating a new resource when no id is available) or a PUT (updating an existing resource when a valid id is available).

This also would allow you to implement a different way of handling the JSON CSRF Vulnerability. The angular.js way is built into $http, but my company's REST API fixes this problem by wrapping JSON arrays in a dummy object. I use a custom resource like the one above to parse the dummy object out.

这篇关于Angularjs - 定制$资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆