@ngdoc overview @name Tutorial: 7 - Routing & Multiple Views @description In this step, you will learn how to create a layout template and how to build an app that has multiple views by adding routing. Note that you are redirected to `app/index.html#/phones` and the same phone list appears in the browser. When you click on a phone link the stub of a phone detail page is displayed. The most important changes are listed below. You can see the full diff on {@link https://github.com/angular/angular-phonecat/compare/step-6...step-7 GitHub}: ## Multiple Views, Routing and Layout Template Our app is slowly growing and becoming more complex. Before step 7, the app provided our users with a single view (the list of all phones), and all of the template code was located in the `index.html` file. The next step in building the app is to add 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. Application routes in angular are declared via the {@link api/angular.service.$route $route} service. This service 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 (back and forward navigation) and bookmarks. ## Controllers __`app/js/controller.js`:__
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'];
...
We created a new controller called `PhoneCatCtrl`. We declared its dependency on the `$route` service and used this service to declare that our application consists of two different views: * The phone list view will be shown when the URL hash fragment is `/phone`. To construct this view, angular will use the `phone-list.html` template and the `PhoneListCtrl` controller. * The phone details view will be shown when the URL hash fragment matches '/phone/:phoneId', where `:phoneId` is a variable part of the URL. To construct the phone details view, angular will use the `phone-detail.html` template and the `PhoneDetailCtrl` controller. We reused the `PhoneListCtrl` controller that we constructed in previous steps and we added a new, empty `PhoneDetailCtrl` controller to the `app/js/controllers.js` file for the phone details view. The statement `$route.otherwise({redirectTo: '/phones'})` triggers a redirection to `/phones` when the browser address doesn't match either of our routes. Thanks to the `$route.parent(this);` statement and `ng:controller="PhoneCatCtrl"` declaration in the `index.html` template, the `PhoneCatCtrl` controller has a special role in our app. It is the "root" controller and the parent controller for the other two sub-controllers (`PhoneListCtrl` and `PhoneDetailCtrl`). The sub-controllers inherit the model properties and behavior from the root controller. Note the use of the `:phoneId` parameter in the second route declaration. The `$route` service uses the route declaration — `'/phones/:phoneId'` — as a template that is matched against the current URL. All variables defined with the `:` notation are extracted into the `$route.current.params` map. The `params` alias created in the {@link api/angular.service.$route `$route.onChange`} callback allows us to use the `phoneId` property of this map in the `phone-details.html` template. ## Template The `$route` service is usually used in conjunction with the {@link api/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. __`app/index.html`:__
...


  

  
  


Note that we removed most of the code in the `index.html` template and replaced it with a single line containing the `ng:view` tag. The code that we removed was placed into the `phone-list.html` template: __`app/partials/phone-list.html`:__



We also added a placeholder template for the phone details view: __`app/partials/phone-list.html`:__
TBD: detail view for {{params.phoneId}}
Note how we are using `params` model defined in the `PhoneCanCtrl` controller. ## Test To automatically verify that everything is wired properly, we wrote end-to-end tests that navigate to various URLs and verify that the correct view was rendered.
...
  it('should redirect index.html to index.html#/phones', function() {
   browser().navigateTo('../../app/index.html');
   expect(browser().location().hash()).toBe('/phones');
  });
...

 describe('Phone detail view', function() {

   beforeEach(function() {
      browser().navigateTo('../../app/index.html#/phones/nexus-s');
   });


   it('should display placeholder page with phoneId', function() {
      expect(binding('params.phoneId')).toBe('nexus-s');
   });
 });
You can now refresh the browser tab with the end-to-end test runner to see the tests run, or you can see them running on {@link http://angular.github.com/angular-phonecat/step-7/test/e2e/runner.html angular's server}. # Experiments * Try to add an `{{orderProp}}` binding to `index.html`, and you'll see that nothing happens even when you are in the phone list view. This is because the `orderProp` model is visible only in the scope managed by `PhoneListCtrl`, which is associated with the `` element. If you add the same binding into the `phone-list.html` template, the binding will work as expected. * In `PhoneCatCtrl`, create a new model called "`hero`" with `this.hero = 'Zoro'`. In `PhoneListCtrl` let's shadow it with `this.hero = 'Batman'`, and in `PhoneDetailCtrl` we'll use `this.hero = "Captain Proton"`. Then add the `

hero = {{hero}}

` to all three of our templates (`index.html`, `phone-list.html`, and `phone-detail.html`). Open the app and you'll see scope inheritance and model property shadowing do some wonders. # Summary With the routing set up and the phone list view implemented, we're ready to go to step 8 to implement the phone details view. 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384