1.切換分支到step7,並啟動項目git checkout step-7npm start2.需求:在步驟7之前,應用只給我們的使用者提供了一個簡單的介面(一張所有手機的列表),並且所有的模板代碼位於index.html檔案中。下一步是增加一個能夠顯示我們列表中每一部手機詳細資料的頁面。可以先看一下step6和7的代碼區別 . 為了增加詳細資料檢視,我們可以拓展index.html來同時包含兩個視圖的模板代碼,但是這樣會很快給我們帶來巨大的麻煩。相反,我們要把index.html模板轉變成“布局模板”。這是我們應用所有視圖的通用模板。其他的“局部布局模板”隨後根據當前的“路由”被充填入,從而形成一個完整視圖展示給使用者。 AngularJS中應用的路由通過$routeProvider來聲明,它是$route服務的提供者。這項服務使得控制器、視圖模板與當前瀏覽器的URL可以輕易整合。應用這個特性我們就可以實現深連結,它允許我們使用瀏覽器的曆史(回退或者前進導航)和書籤。 可以很明顯的注意到當訪問 http://localhost:8000/app時,其URL被重新導向到了http://localhost:8000/app/#/phones頁面. 4.實現代碼app/index.html 複製代碼<!doctype html><html lang="en" ng-app="phonecatApp"><head> <meta charset="utf-8"> <title>Google Phone Gallery</title> <link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.css"> <link rel="stylesheet" href="css/app.css"> <script src="../bower_components/angular/angular.js"></script> <script src="../bower_components/angular-route/angular-route.js"></script> <script src="js/app.js"></script> <script src="js/controllers.js"></script></head><body> <div ng-view></div> </body></html>複製代碼可以發現其實現代碼非常簡單,只有一個div標籤, 然後一個ng-view指令.同時要注意的是引入了angular.js、angular-route.js、app.js和controllers.js,這裡將按照順序貼出其js代碼.並加以說明. app/app.js 複製代碼'use strict'; /* App Module */ var phonecatApp = angular.module('phonecatApp', [ 'ngRoute', 'phonecatControllers']); phonecatApp.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/phones', { templateUrl: 'partials/phone-list.html', controller: 'PhoneListCtrl' }). when('/phones/:phoneId', { templateUrl: 'partials/phone-detail.html', controller: 'PhoneDetailCtrl' }). otherwise({ redirectTo: '/phones' }); }]);複製代碼app/controllers.js 複製代碼'use strict'; /* Controllers */ var phonecatControllers = angular.module('phonecatControllers', []); phonecatControllers.controller('PhoneListCtrl', ['$scope', '$http', function($scope, $http) { $http.get('phones/phones.json').success(function(data) { $scope.phones = data; }); $scope.orderProp = 'age'; }]); phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', function($scope, $routeParams) { $scope.phoneId = $routeParams.phoneId; }]);複製代碼 app/partials/phone-detail.html: TBD: detail view for {{phoneId}} 代碼說明: 1).index.html中<html lang="en" ng-app="phonecatApp">定義了要使用的ng-app是"phoneApp",然後定義了:<div ng-view></div>,這裡可以ngView:查看一下ng-view的api說明,ngView ,ngView是一個指令,主要用於通過已經渲染的模板將當前的$route服務與首頁面(index.html)連接起來. ngView is a directive that complements the $route service by including the rendered template of the current route into the main layou (index.html) file. Every time the current route changes, the included view changes with it according to the configuration of the$route service. 用法: as element: (This directive can be used as custom element, but be aware of IE restrictions).<ng-view [onload=""] [autoscroll=""]>...</ng-view>as attribute:<ANY [onload=""] [autoscroll=""]>...</ANY>as CSS class:<ANYclass="[onload: ;] [autoscroll: ;]"> ... </ANY>在本例中用到的是as CSS class,這裡ngview是要和$route成隊使用的. 2).關於app.js 為了給我們的應用配置路由,我們需要給應用建立一個模組。我們管這個模組叫做phonecat,並且通過使用configAPI,我們請求把$routeProvider注入到我們的配置函數並且使用$routeProvider.when API來定義我們的路由規則。 注意到在注入器設定階段,提供者也可以同時被注入,但是一旦注入器被建立並且開始建立服務執行個體的時候,他們就不再會被外界所擷取到。 我們的路由規則定義如下 當URL 對應段為/phones時,手機列表視圖會被顯示出來。為了構造這個視圖,AngularJS會使用phone-list.html模板和PhoneListCtrl控制器。當URL 對應段為/phone/:phoneId時,手機詳細資料檢視被顯示出來。這裡:phoneId是URL的變數部分。為了構造手機詳細視圖,AngularJS會使用phone-detail.html模板和PhoneDetailCtrl控制器。我們重用之前創造過的PhoneListCtrl控制器,同時我們為手機詳細視圖添加一個新的PhoneDetailCtrl控制器,把它存放在app/js/controllers.js檔案裡。$route.otherwise({redirectTo: '/phones'})語句使得當瀏覽器地址不能匹配我們任何一個路由規則時,觸發重新導向到/phones。 注意到在第二條路由聲明中:phoneId參數的使用。$route服務使用路由聲明/phones/:phoneId作為一個匹配當前URL的模板。所有以:標記法宣告的變數(此處變數為phones)都會被提取,然後存放在$routeParams對象中。 3).app/js/controllers.js 這裡用的是$http get方法將phones/phones.json的值讀取出來;定義phonecatControllers,並配置phonecatControllers,將$routeParams作為變數,將值再賦給$scope.phoneId ,然後顯示的routeParams.phoneId; 4) phone-detail.html phone-detail.html中將控制器裡phoneId的值顯示出來. 5.測試執行如下命令開始測試: amosli@amosli-pc:~/develop/angular-phonecat$ npm run protractorangular-phonecat/test/e2e/scenarios.js View Code 測試結果: Using ChromeDriver directly........ Finished in 7.368 seconds5 tests, 8 assertions, 0 failures