aboutsummaryrefslogtreecommitdiffstats
path: root/docs/tutorial.step_5.ngdoc
blob: 3480e43750705ab3bf4b5cb3893226470346748c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
@workInProgress
@ngdoc overview
@name Tutorial: Step 5
@description
<table id="tutorial_nav">
<tr>
 <td id="previous_step">{@link tutorial.step_4 Previous}</td>
 <td id="step_result">{@link  http://angular.github.com/angular-phonecat/step-5/app Example}</td>
 <td id="tut_home">{@link tutorial Tutorial Home}</td>
 <td id="code_diff">{@link
 https://github.com/angular/angular-phonecat/commit/4f0a518557b5c7442568666b211aa79499870276 Code
 Diff}</td>
 <td id="next_step">{@link tutorial.step_6 Next}</td>
</tr>
</table>

In this step, the View template remains the same but the Model and Controller change.  We'll
introduce the use of an angular {@link angular.service service}, which we will use to implement an
`HttpXmlRequest` request to communicate with a server. Angular provides the built-in {@link
angular.service.$xhr $xhr} service for this purpose.

The addition of the `$xhr` service to our app gives us the opportunity to talk about {@link
guide.di Dependency Injection} (DI).  The use of DI is another cornerstone of the angular
philosophy. DI helps make your web apps well structured, loosely coupled, and ultimately easier to
test.  

__`app/js/controllers.js:`__
<pre>
/* App Controllers */

function PhoneListCtrl($xhr) {
  var self = this;

  $xhr('GET', 'phones/phones.json', function(code, response) {
    self.phones = response;
  });

  self.orderProp = 'age';
}

//PhoneListCtrl.$inject = ['$xhr'];
</pre>

__`test/unit/controllerSpec.js`:__
<pre>
/* jasmine specs for controllers go here */
describe('PhoneCat controllers', function() {

  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).toBeUndefined();
      $browser.xhr.flush();

      expect(ctrl.phones).toEqual([{name: 'Nexus S'},
                                   {name: 'Motorola DROID'}]);
    });


    it('should set the default value of orderProp model', function() {
      expect(ctrl.orderProp).toBe('age');
    });
  });
});
</pre>

## Discussion:

* __Services:__ {@link angular.service Services} are substitutable objects managed by angular's
{@link guide.di DI subsystem}.  Angular services simplify some of the standard operations common
to web apps.  Angular provides several built-in services (such as {@link angular.service.$xhr
$xhr}). You can also create your own custom services.

* __Dependency Injection:__ To use an angular service, you simply provide the name of the service
as a parameter to the function in which you are using that service. Angular's {@link guide.di DI
subsystem} recognizes the identity of the service by name, provides it for you when you need it,
and manages any transitive dependencies the service may have (services often depend upon other
services).

* __`$xhr`:__ We moved our data set out of the controller and into the file `phones/phones.json`. 
This file serves as our data store rather than an actual server (to the browser they look the
same).  We now use the `$xhr` service to return our phone data, which you'll note is still within
the scope of our controller function. 

* __Testing:__  The unit test has been expanded.  It now verifies that the `$xhr` service behaves
as expected.

<table id="tutorial_nav">
<tr>
 <td id="previous_step">{@link tutorial.step_4 Previous}</td>
 <td id="step_result">{@link  http://angular.github.com/angular-phonecat/step-5/app Example}</td>
 <td id="tut_home">{@link tutorial Tutorial Home}</td>
 <td id="code_diff">{@link
 https://github.com/angular/angular-phonecat/commit/4f0a518557b5c7442568666b211aa79499870276 Code
 Diff}</td>
 <td id="next_step">{@link tutorial.step_6 Next}</td>
</tr>
</table>