diff options
Diffstat (limited to 'docs/content/tutorial/step_07.ngdoc')
| -rwxr-xr-x | docs/content/tutorial/step_07.ngdoc | 181 | 
1 files changed, 181 insertions, 0 deletions
| diff --git a/docs/content/tutorial/step_07.ngdoc b/docs/content/tutorial/step_07.ngdoc new file mode 100755 index 00000000..802130c5 --- /dev/null +++ b/docs/content/tutorial/step_07.ngdoc @@ -0,0 +1,181 @@ +@workInProgress
 +@ngdoc overview
 +@name Tutorial: Step 7
 +@description
 +<table id="tutorial_nav">
 +<tr>
 +<td id="previous_step">{@link tutorial.step_06 Previous}</td>
 +<td id="step_result">{@link  http://angular.github.com/angular-phonecat/step-7/app Live Demo
 +}</td>
 +<td id="tut_home">{@link tutorial Tutorial Home}</td>
 +<td id="code_diff">{@link https://github.com/angular/angular-phonecat/compare/step-6...step-7 Code
 +Diff}</td>
 +<td id="next_step">{@link tutorial.step_08 Next}</td>
 +</tr>
 +</table>
 +
 +Our app is slowly growing and becoming more complex. Up until now, the app provided our users with
 +just one view (the list of all phones), and all of our template code was located in the
 +`index.html` file.  The next step in building our app is the addition of a view that will show
 +detailed information about each of the devices in our list.
 +
 +To add the detailed view, we could expand the `index.html` file to contain template code for both
 +views, but that would get messy very quickly. Instead, we are going to turn the `index.html`
 +template into what we call a "layout template". This is a template that is common for all views in
 +our application.   Other "partial templates" are then included into this layout template depending
 +on the current "route" — the view that is currently displayed to the user.
 +
 +Similarly as with templates, angular also allows for controllers and scopes managed by these
 +controllers to be nested. We are going to create a "root" controller called `PhoneCatCtrl`, which
 +will contain the declaration of routes for the application.
 +
 +Application routes in angular are declared via the {@link angular.service.$route $route} service.
 +This services makes it easy to wire together controllers, View templates, and the current URL
 +location in the browser.  Using this feature we can implement {@link
 +http://en.wikipedia.org/wiki/Deep_linking deep linking}, which lets us utilize the browser's
 +History, and Back and Forward browser navigation.
 +
 +We'll use the $route service to declare that our application consists of two different views: one
 +view presents the phone listing, and the other view presents the details for a particular phone.
 +Each view will have the template stored in a separate file in the `app/partials/` directory.
 +Similarly each view will have a controller associated with it. These will be stored in the
 +existing `app/js/controllers.js` file.
 +
 +The `$route` service is usually used in conjunction with the {@link angular.widget.ng:view
 +ng:view} widget. The role of the `ng:view` widget is to include the view template for the current
 +route into the layout template, which makes it a perfect fit for our `index.html` template.
 +
 +For now we are going to get all the routing going, and move the phone listing template into a
 +separate file. We'll save the implementation of the phone details View for the next step.
 +
 +__`app/index.html`:__
 +<pre>
 +...
 +<body ng:controller="PhoneCatCtrl">
 +
 +  <ng:view></ng:view>
 +
 +  <script src="lib/angular/angular.js" ng:autobind></script>
 +  <script src="js/controllers.js"></script>
 +</body>
 +</html>
 +</pre>
 +
 +__`app/partials/phone-list.html`:__
 +<pre>
 +<ul class="predicates">
 +  <li>
 +    Search: <input type="text" name="query"/>
 +  </li>
 +  <li>
 +    Sort by:
 +    <select name="orderProp">
 +      <option value="name">Alphabetical</option>
 +      <option value="age">Newest</option>
 +    </select>
 +  </li>
 +</ul>
 +
 +<ul class="phones">
 +  <li ng:repeat="phone in phones.$filter(query).$orderBy(orderProp)">
 +    <a href="#/phones/{{phone.id}}">{{phone.name}}</a>
 +    <a href="#/phones/{{phone.id}}" class="thumb"><img ng:src="{{phone.imageUrl}}"></a>
 +    <p>{{phone.snippet}}</p>
 +  </li>
 +</ul>
 +</pre>
 +
 +__`app/partials/phone-list.html`:__
 +<pre>
 +TBD: detail view for {{params.phoneId}}
 +</pre>
 +
 +__`app/js/controller.js`:__
 +<pre>
 +/* App Controllers */
 +
 +function PhoneCatCtrl($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);
 +}
 +
 +//PhoneCatCtrl.$inject = ['$route'];
 +
 +
 +function PhoneListCtrl($xhr) {
 +  var self = this;
 +
 +  $xhr('GET', 'phones/phones.json', function(code, response) {
 +    self.phones = response;
 +  });
 +
 +  self.orderProp = 'age';
 +}
 +
 +//PhoneListCtrl.$inject = ['$xhr'];
 +
 +
 +function PhoneDetailCtrl() {}
 +</pre>
 +
 +## Discussion:
 +
 +* __The View.__ Our View template in `index.html` has been reduced down to this:
 +`<ng:view></ng:view>`.  As described above, it is now a "layout template". We added the following
 +two new View templates:
 +
 +    * `app/partials/phone-list.html` for the phone list.  The phone-list view was formerly our
 +    main view. We simply moved the code from `index.html` to here.
 +
 +    * `app/partials/phone-detail.html` for the phone details (just a placeholder template for now).
 +
 +* __The Controller(s).__ We now have a new root controller (`PhoneCatCtrl`) and two
 +sub-controllers (`PhoneListCtrl` and `PhoneDetailCtrl`). These inherit the model properties and
 +behavior from the root controller.
 +
 +    * __`$route.`__ The root controller's job now is to set up the `$route` configuration:
 +
 +        * When the fragment part of the URL in the browser ends in "/phones", `$route` service
 +        grabs the `phone-list.html` template, compiles it, and links it with a new scope that is
 +        controlled by our `PhoneListCtrl` controller.
 +
 +        * When the URL ends in "/phones/:phoneId", `$route` compiles and links the
 +        `phone-detail.html` template as it did with `phone-list.html`. But note the use of the
 +        `:phoneId` parameter declaration in the `path` argument of `$route.when()`: `$route`
 +        services provides all the values for variables defined in this way as
 +        `$route.current.params` map. In our route, `$route.current.params.phoneId` always holds
 +        the current contents of the `:phoneId` portion of the URL. We will use the `phoneId`
 +        parameter when we fetch the phone details in Step 8.
 +
 +        * Any other URL fragment gets redirected to `/phones`.
 +
 +    * __Controller/Scope inheritance.__ In the function passed into `$route`'s `onChange()`
 +    method, we copied url parameters extracted from the current route to the `params` property in
 +    the root scope. This property is inherited by child scopes created for our view controllers
 +    and accessible by these controllers.
 +
 +  * __Tests.__ To automatically verify that everything is wired properly, we write end to end
 +  tests that navigate to various URLs and verify that the correct view was rendered.
 +
 +<table id="tutorial_nav">
 +<tr>
 +<td id="previous_step">{@link tutorial.step_06 Previous}</td>
 +<td id="step_result">{@link  http://angular.github.com/angular-phonecat/step-7/app Live Demo
 +}</td>
 +<td id="tut_home">{@link tutorial Tutorial Home}</td>
 +<td id="code_diff">{@link https://github.com/angular/angular-phonecat/compare/step-6...step-7 Code
 +Diff}</td>
 +<td id="next_step">{@link tutorial.step_08 Next}</td>
 +</tr>
 +</table>
 | 
