From e205bd7137fd793d223dbe3e020a628f8e7d98f3 Mon Sep 17 00:00:00 2001 From: Kenneth R. Culp Date: Fri, 29 Apr 2011 10:04:40 -0700 Subject: Update tutorial docs. --- docs/tutorial.step_11.ngdoc | 131 +++++++++++++++++++++++++++++++++----------- 1 file changed, 98 insertions(+), 33 deletions(-) (limited to 'docs/tutorial.step_11.ngdoc') diff --git a/docs/tutorial.step_11.ngdoc b/docs/tutorial.step_11.ngdoc index b770caea..34ba7b02 100644 --- a/docs/tutorial.step_11.ngdoc +++ b/docs/tutorial.step_11.ngdoc @@ -5,26 +5,23 @@ - + - +
{@link tutorial.step_10 Previous}{@link http://angular.github.com/angular-phonecat/step-11/app Example}{@link http://angular.github.com/angular-phonecat/step-11/app Live Demo +} {@link tutorial Tutorial Home}{@link -https://github.com/angular/angular-phonecat/commit/46e2bc3ff21a1385d6ef1860c5c242f8e0265379 Code -Diff}{@link https://github.com/angular/angular-phonecat/compare/step-10...step-11 +Code Diff} Next
And so we arrive at the last step of this tutorial. Here we define a custom service that -represents a {@link http://en.wikipedia.org/wiki/Representational_State_Transfer RESTful} client -object. Using this client object we can make requests for data in an easier way, without having -to deal with the lower-level {@link angular.service.$xhr $xhr} APIs. +represents a {@link http://en.wikipedia.org/wiki/Representational_State_Transfer RESTful} client. +Using this client we can make xhr requests for data in an easier way, without having to deal with +the lower-level {@link angular.service.$xhr $xhr} APIs, HTTP methods and URLs. __`app/index.html`.__
 ...
-  
-  
-  
   
 ...
 
@@ -41,34 +38,85 @@ __`app/js/services.js`.__ (New) __`app/js/controllers.js`.__
-function PhonesCtrl($route) {
-  var self = this;
-
-  $route.when('/phones',
-             {template:'partials/phone-list.html',   controller:PhoneListCtrl});
-  $route.when('/phones/:phoneId',
-             {template:'partials/phone-detail.html', controller:PhoneDetailCtrl});
-  $route.otherwise({redirectTo:'/phones'});
-
-  $route.onChange(function(){
-    self.params = $route.current.params;
-  });
-  $route.parent(this);
-}
-//PhonesCtrl.$inject = ['$route'];
+...
 
-function PhoneListCtrl(Phone) {
+function PhoneListCtrl(Phone_) {
   this.orderProp = 'age';
-  this.phones = Phone.query();
+  this.phones = Phone_.query();
 }
 //PhoneListCtrl.$inject = ['Phone'];
 
 
-function PhoneDetailCtrl(Phone) {
-  this.phone = Phone.get({phoneId:this.params.phoneId});
+function PhoneDetailCtrl(Phone_) {
+  this.phone = Phone_.get({phoneId:this.params.phoneId});
 }
 //PhoneDetailCtrl.$inject = ['Phone'];
+
+ +__`test/unit/controllersSpec.js`:__ +
+/* jasmine specs for controllers go here */
+describe('PhoneCat controllers', function() {
+
+  beforeEach(function(){
+    this.addMatchers({
+      toEqualData: function(expected) {
+        return angular.equals(this.actual, expected);
+      }
+    });
+  });
+
+  describe('PhoneListCtrl', function(){
+    var scope, $browser, ctrl;
+
+    beforeEach(function() {
+      scope = angular.scope();
+      $browser = scope.$service('$browser');
+
+      $browser.xhr.expectGET('phones/phones.json').respond([{name: 'Nexus S'},
+                                                            {name: 'Motorola DROID'}]);
+      ctrl = scope.$new(PhoneListCtrl);
+    });
+
+    it('should create "phones" model with 2 phones fetched from xhr', function() {
+      expect(ctrl.phones).toEqual([]);
+      $browser.xhr.flush();
 
+      expect(ctrl.phones).toEqualData([{name: 'Nexus S'},
+                                       {name: 'Motorola DROID'}]);
+    });
+
+    it('should set the default value of orderProp model', function() {
+      expect(ctrl.orderProp).toBe('age');
+    });
+  });
+
+
+  describe('PhoneDetailCtrl', function(){
+    var scope, $browser, ctrl;
+
+    beforeEach(function() {
+      scope = angular.scope();
+      $browser = scope.$service('$browser');
+    });
+
+    beforeEach(function() {
+      scope = angular.scope();
+      $browser = scope.$service('$browser');
+    });
+
+    it('should fetch phone detail', function(){
+      scope.params = {phoneId:'xyz'};
+      $browser.xhr.expectGET('phones/xyz.json').respond({name:'phone xyz'});
+      ctrl = scope.$new(PhoneDetailCtrl);
+
+      expect(ctrl.phone).toEqualData({});
+      $browser.xhr.flush();
+
+      expect(ctrl.phone).toEqualData({name:'phone xyz'});
+    });
+  });
+});
 
@@ -80,9 +128,26 @@ angular.service.$resource `$resource`} service is easier to use than `$xhr` for data sources exposed as RESTful resources. It is also easier now to understand what the code in our controllers is doing. + An important thing to notice in our controller code is that we don't pass any callback + functions when invoking methods of our Phone services. It looks as if the result were returned + synchronously. That is not the case at all. What is returned synchronously is a "future" — an + object, which will be filled with data when the xhr response returns. Because of the + data-binding in angular, we can use this future and bind it to our template. Then, when the + data arrives, the view will automatically update. See? Angular tries hard to make simple + stuff simple. + * Once again we make use of `$route's` params, this time to construct the URL passed as a parameter to `$resource` in our `services.js` script. +* Last, but certainly not least, we expanded and modified our unit test to verify that our new +service is returning data as we expect it to. + + In our assertions we use a newly-defined `toEqualData` {@link + http://pivotal.github.com/jasmine/jsdoc/symbols/jasmine.Matchers.html Jasmine matcher}, which + compares only object properties and ignores methods. This is necessary, because the `$resource` + client will augment the response object with handy methods for updating and deleting the + resource (we don't use these in our tutorial though). + There you have it! We have created a web app in a relatively short amount of time. ## Closing Notes: @@ -103,11 +168,11 @@ to angular. - + - +
{@link tutorial.step_10 Previous}{@link http://angular.github.com/angular-phonecat/step-11/app Example}{@link http://angular.github.com/angular-phonecat/step-11/app Live Demo +} {@link tutorial Tutorial Home}{@link -https://github.com/angular/angular-phonecat/commit/46e2bc3ff21a1385d6ef1860c5c242f8e0265379 Code -Diff}{@link https://github.com/angular/angular-phonecat/compare/step-10...step-11 +Code Diff} Next
-- cgit v1.2.3