ANGULARJS Learning---Rest and customization services (rest and custom service) Ngresource step 11

Source: Internet
Author: User

1. Switch directories
git checkout step-onenpm start
2.

and step 10 no difference, here the main changes are the code, the code has done a lot of optimization, here is no longer posted.

3. Implementing the Code

the difference between step-10 and step-11:https://github.com/angular/angular-phonecat/compare/step-10...step-11

Dependencies (Dependent JS):

 { "name": "Angular-seed"  "description": "A starter Project for AngularJS" " version ":" 0.0.0 " " homepage ":" Https://github.com/angular/angular-seed ",  "license": "MIT" " private ": true  " dependencies " "angular" : "1.2.x" " angular-mocks ":" ~1.2.x " ,  "bootstrap": "~3.1.1" " Angular-route ":" ~1.2.x ",   "Angular-resource": "~1.2.x"  }}  

Here is Bower to manage JS library, add Angular-resource.js, this is through the NPM install or Bower install command to download angular-resource.js file.

Templates (template layer)

App/index.html

...   <  src= "Bower_components/angular-resource/angular-resource.js"></  Script>  <src= "Js/services.js">< /script> ...

Note: Angular-resource.js is introduced here, about Ngresource can be viewed Api:https://docs.angularjs.org/api/ngresource

Service (services Tier)

app/js/services.js.

var phonecatservices = angular.module (' phonecatservices ', [' Ngresource ']);p honecatservices.factory ( ' Phone ', [' $resource ',  function($resource) {    return $resource (' phones/:p Honeid.json ', {}, {      query: {method:' GET ', Params:{phoneid: ' Phones '}, IsArray:true }    });  }]);

We use the module API to register a custom service through a factory method. We pass in the name of the service Phone and the factory function. Factory functions and controller constructors are similar in that they all declare dependent services through function arguments. The phone service declares that it relies on $resource services.

$resource service allows you to create a restful client with just a few lines of code. Our application uses this client instead of the underlying $http service.

In fact, its internal implementation or through the $http way to obtain data, here is just a layer of additional packaging.

Usage of $resource :

$resource (URL, [paramdefaults], [Actions], options);

Controller (Controllers)

app/js/controllers.js.

varPhonecatcontrollers = Angular.module (' phonecatcontrollers '), []); ... phonecatcontrollers.controller (' Phonelistctrl ', [' $scope ', ' Phone ',function($scope, Phone) {$scope. Phones=Phone.query (); $scope. Orderprop= ' Age ';}]); Phonecatcontrollers.controller (' Phonedetailctrl ', [' $scope ', ' $routeParams ', ' Phone ',function($scope, $routeParams, phone) {$scope. Phone= Phone.get ({phoneid: $routeParams. Phoneid},function(phone) {$scope. Mainimageurl= Phone.images[0];  }); $scope. SetImage=function(IMAGEURL) {$scope. Mainimageurl=ImageUrl; }}]);

by refactoring the underlying $http service, put it in a new service Phone , we can greatly simplify the sub-controller ( PhoneListCtrl and the PhoneDetailCtrl ). Angularjs's $resource is $http better suited to interacting with a restful data source than it is. And now it's easier to understand what the controller code is doing.

Note the replacement of the code:

-phonecatcontrollers.controller (' Phonelistctrl ', [' $scope ', ' $http '-  function-    $http. Get (' Phones/phones.json '). Success (function-      $scope. Phones =-      -+phonecatcontrollers.controller (' Phonelistctrl ', [' $scope ', ' Phone '+  function + $scope. Phones = Phone.query ();              = ' age ';    }]);

---means replaced) (i.e., deleted), + + + represents the replacement (i.e., the newly added).

The packaging for actions in $resource here is as follows:

{' Get ':    {method: ' GET '},    ' Save ':   {method: ' POST '},    ' query ':  {method: ' GET ', IsArray:true},     ' Remove ': {method: ' delete '},    ' delete ': {method: ' delete '}};

Here is the Get method. we use this simple statement to query all the phones.

Another very important note is that in the above code, when calling the phone service, we do not pass any callback functions. Although this seems to be the result of a synchronous return, it is not actually at all. The synchronization returned is a "future"-an object that is populated with data when the XHR is returned accordingly. Given the ANGULARJS data binding, we can use the future and bind it to our template. Then, when the data arrives, our view is automatically updated.

Sometimes, relying solely on future objects and data binding is not enough to meet our needs, so in these cases we need to add a callback function to handle the server's response. PhoneDetailCtrlthe controller is interpreted by setting it in a callback function mainImageUrl .

4. Testing

Modify our unit tests to verify that our new service initiates HTTP requests and processes them as expected. The test also checks to see if our controller is working properly with the service.

$resource service enhances the resulting object by adding methods for updating and deleting resources. If we are going to use toEqual a match, our test will fail because the test value will not be exactly the same as the response. To solve this problem, we need to use a recently defined toEqualData Jasmine match. When a toEqualData match is compared to two objects, it only takes into account the properties of the object and ignores all methods.

test/unit/controllersSpec.js:

Describe (' Phonecat controllers ',function() {Beforeeach (function(){     This. Addmatchers ({toequaldata:function(expected) {returnAngular.equals ( This. Actual, expected);  }    });  }); Beforeeach (Module (' Phonecatapp ')); Beforeeach (Module (' Phonecatservices ')); Describe (' Phonelistctrl ',function(){    varscope, CTRL, $httpBackend; Beforeeach (Inject (function(_$httpbackend_, $rootScope, $controller) {$httpBackend=_$httpbackend_; $httpBackend. Expectget (' Phones/phones.json '). Respond ([{name:' Nexus S '}, {name: ' Motorola DROID '}]); Scope= $rootScope. $New(); CTRL=$controller (Phonelistctrl, {$scope: scope});    })); It (' should create ' phones ' model with 2 phones fetched from XHR ',function() {expect (scope.phones). Toequaldata ([]);      $httpBackend. Flush (); Expect (Scope.phones). Toequaldata ([{name:' Nexus S '}, {name: ' Motorola DROID '}]);    }); It (' should set the default value of Orderprop model ',function() {expect (Scope.orderprop). ToBe (' Age ');  });  }); Describe (' Phonedetailctrl ',function(){    varscope, $httpBackend, CTRL, Xyzphonedata=function() {          return{name:' Phone xyz ', images: [' Image/url1.png ', ' image/url2.png ']          }        }; Beforeeach (Inject (function(_$httpbackend_, $rootScope, $routeParams, $controller) {$httpBackend=_$httpbackend_; $httpBackend. Expectget (' Phones/xyz.json '). Respond (Xyzphonedata ()); $routeParams. Phoneid= ' xyz '; Scope= $rootScope. $New(); CTRL=$controller (Phonedetailctrl, {$scope: scope});    })); It (' Should fetch phone detail ',function() {expect (Scope.phone). Toequaldata ({});      $httpBackend. Flush ();    Expect (Scope.phone). Toequaldata (Xyzphonedata ());  }); });});

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.