RESTful resources in the ANGULARJS
Palwo
Posted on 2014-12-16 17:31:50
The $http service provides a very low-level implementation that can be used to send XHR requests, while also providing you with great controllability and flexibility. However, in most cases, we need to work with objects and object models that encapsulate specific properties and methods, such as a person object (with details), or a credit card object.
In these cases, would it be great if we could create a JS object and it could understand and represent the object model? If we just edit the properties of this object, such as Save or update, will these states be persisted to the server?
$resource is designed for this function. The resource (Resource) in Angularjs allows us to define the object model in a descriptive way, which can describe the following:
1. The URL of the resource on the server side.
2. Common request parameter types.
3. Some additional methods (you can automatically get the GET, save, query, remove, and Delete methods), which wrap specific functionality and business logic (such as the charge () method of the credit card object) for the object model.
4. Desired response type (an array or an object).
5. Protocol header.
Using the $resource object provided by angular, you can query the server based on various requirements, but you can also use the objects returned by the service as a well-persisted data model, you can modify them, and you can persist them.
The Ngresource is a standalone, optional module. In order to use it, you need:
A. Include angular-resource.js in the loaded script file
B. Include Ngresource (for example, Angular.module (' MyModule ', [' Ngresource ']) in the module dependency declaration.
C. Use of injected $resource services where needed.
Before learning how to use the Ngresource method to create a resource, let's take a look at what needs to be done to create something similar using the basic $http service. For our credit card resources, in addition to being able to do a "change" (charge) operation, we also have to be able to get (get), query, and save (save) the credit card.
The following is a possible implementation:
Myappmodule.factory (' CreditCard ', [' http ', function ($http) {var baseUrl = '/user/123/card '; return {get:function (cardi d) {return $http. Get (BaseUrl + '/' + cardId), Save:function (card) {var url = card.id? baseUrl + '/' + card.id:base URL; Return $http. Post (URL, card), Query:function () {return $http. Get (BASEURL);}, Charge:function (card) {return $http. pos T (baseUrl + '/' + card.id, card, {params: {charge:true}});};}]);
In addition to this approach, you can simply create a angular service that describes the resources provided by the application in the following ways:
Myappmodule.factory (' CreditCard ', [' $resource ', function ($resource) {return $resource ('/usr/:userid/card/:cardid ', {userid:123, cardId: ' @id '}, {charge: {method: ' POST ', params: {charge:true}, Isarray:false},}]);
Now, as long as we angularjs the syringe to request a CreditCard instance, we can get a angular resource, which by default gives us some basic methods. The following table lists the contents of these methods and their behavior, and with this information you will know how to configure the service side. Let's look at an example of a credit card, which will make our thinking clearer.
Suppose the CreditCard service is injected here//We can get a collection from the server, the requested path is Get:/user/123/cardvar cards = creditcard.query ();// We can also get and use a single credit card in the callback function Creditcard.get ({cardid:456}, function (card) {//Each instance is CreditCard type expect (card instanceof CreditCard). Toequal (True); Card.name = "J.smith";//the Non-get-type method is mapped to the instance card. $save ();//Our custom method is also mapped to the card. $charge ({amount:9.99});//Initiate a POST request:/ User/123/card/456?amount=9.99&charge=true//The data passed when sending the request is: {id:456, Number: ' 1234 ', Name: ' J.smith '}});
This example involves more content, which is more important in the following sequence:
I. Declaration
Whether you are customizing the $resource, or using the correct parameters to invoke the injected $resource function, the operation is very simple.
The $resource function has a required parameter, the URL address of the available resource, and two optional parameters, the default parameter and the additional action you want to configure on the resource.
Note that the URL is parameterized (with: to identify the parameter.) : The userid indicates that the UserID will be replaced with the corresponding text: Cardid indicates that it will be replaced by the value of the Cardid argument. If no arguments are passed, the corresponding identifier is replaced with an empty string.
The second parameter is responsible for handling the default values that will be sent in each request. In the current example, we will pass the constant 123 to the UserID. Parameter Cardid more interesting, "Cardid is" @id. " That is, if we are using an object returned from the server, the id attribute value on the object will be assigned to the Cardid parameter when any method on the object is called (for example, the $save method of the calling object).
The third argument is another function, and we want to expose this function on a custom resource.
Two. Custom Methods
When $resource is called, the third argument passed is an optional one. The method we want to expose on our own resources.
In the previous example, we specified a charge method that can be configured by passing an object that is the name of the method that needs to be exposed. What you need to specify in a configuration item is the type of request (GET, post, etc.), the parameter that needs to be passed as part of the request (in this case, charge=true), and whether the returned result is an array (not in this case). Once you've done these things, you'll be free to call Creditcard.charge ().
Description: This is a very flexible coding style, according to the above code, for the configuration object {charge: {method: ' POST ', params: {charge:true}, Isarray:false},angular will parse it into a method, The method is then bound to the returned RESTful object, and the above configuration object is interpreted as follows:
Creditcard.charge = function (charge, IsArray) {//This is the method body}
Three. Don't use callbacks! (unless you really need them)
The third element to note is the return value type when the resource is called. Please look again at the Creditcard.query () call, we directly assign the credit card object to the cards variable, and do not enter and assign values in the callback function. You might be concerned that this code can run in the case of an asynchronous request to the server?
It is reasonable of you to worry. But in fact, this code is completely correct and can run. What happens here is that Angularjs assigns a reference to the card object (an object or an array, exactly what needs to be based on the expected return value type), and at some point in the future, the reference will be truly assigned when the request to the server is returned. During some periods, the reference object is always empty.
For ANGULARJS applications, the most common process is to fetch data to the server, assign the data to the variable, and then display the data to the template. This quick and easy way is very useful. In the controller code, the only thing you have to do is initiate a call to the server, assign the return value to the correct scope variable, and let the template automatically take care of rendering it. Since the card variable is bound to the view using the data-binding technique of the {{}}, it is not a problem to give it a null value at first, and so on when the asynchronous response returns and then assigns the result to it. At this point the angular data binding mechanism immediately discovers that the data has changed and then automatically notifies the view to refresh. As you can see from here, much of the processing of asynchronous calls has undergone slight changes when using the angular framework.
This approach will not work if you have some business logic that relies on the return value to execute. In this case, you need to use a callback function that will be used when calling Creditcard.get ().
Four. Simplify service-side operations
Whether you use a shortcut to return a value or use a callback function, there are some considerations for returning objects. The return value is not a normal JS object, but rather an "resource" type of object. This means that, in addition to the data returned by the server, it carries some additional behavior (in this case, $save () and $charge ()). This makes it easier to make server-side calls, such as fetching data, modifying data, and persisting the modified content to the server (that is, crud operations that are common in many applications).
Five. When you can use angular resources
You can use angular resources only when the server is working in a restful way. For credit card scenarios, it requires:
1. A GET request to/user/123/card returns a list of 123 credit cards for the user.
2. A GET request to/USER/123/CARD/15 returns a credit card with ID 15 for user 123.
3. A POST request to/user/123/card, with credit card information in the post data, will create a new credit card for the user 123 ID.
4. A POST request to/USER/123/CARD/15, with the credit card information in the post data, will update the credit card information for user 123 with ID 15.
5. A delete request to/USER/123/CARD/15 will delete the credit card information for user 123 with ID 15.
Angularjs $resource RESTful API