歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

AngularJS入門講解4:多視圖,事件綁定,$resource服務講解

上一課,大家知道,手機詳細模板我們沒有寫出來,使用的是一個占位模板。

這一課,我們先實現手機詳細信息視圖,這個視圖會在用戶點擊手機列表中的一部手機時被顯示出來。

為了實現手機詳細信息視圖,我們將會使用$http來獲取數據。

以下json對象就是手機詳細的信息,我們會在手機詳細信息視圖中顯示這些數據。

{
  "additionalFeatures": "Contour Display, Near Field Communications (NFC),...",
  "Android": {
      "os": "Android 2.3",
      "ui": "Android"
  },
  ...
  "images": [
      "img/phones/nexus-s.0.jpg",
      "img/phones/nexus-s.1.jpg",
      "img/phones/nexus-s.2.jpg",
      "img/phones/nexus-s.3.jpg"
  ],
  "storage": {
      "flash": "16384MB",
      "ram": "512MB"
  }
}

 

我們使用$http服務獲取數據,以此來拓展我們的PhoneDetailCtrl控制器。這和之前手機列表控制器的工作方式是一樣的。

function PhoneDetailCtrl($scope, $routeParams, $http) {
  $http.get('phones/' + $routeParams.phoneId + '.json').success(function(data) {
    $scope.phone = data;
  });
}

phone-detail.html文件中原有的TBD占位行已經被手機詳細信息替換掉了。注意到,這裡我們使用AngularJS的{{表達式}}標記和ngRepeat來在視圖中渲染數據模型。

 

<img ng-src="{{phone.images[0]}}" class="phone">

<h1>{{phone.name}}</h1>

<p>{{phone.description}}</p>

<ul class="phone-thumbs">
  <li ng-repeat="img in phone.images">
    <img ng-src="{{img}}">
  </li>
</ul>

<ul class="specs">
  <li>
    <span>Availability and Networks</span>
    <dl>
      <dt>Availability</dt>
      <dd ng-repeat="availability in phone.availability">{{availability}}</dd>
    </dl>
  </li>
    ...
  </li>
    <span>Additional Features</span>
    <dd>{{phone.additionalFeatures}}</dd>
  </li>
</ul>

 

然後,我們在程序中創建自己的過濾器。

為了創建一個新的過濾器,我們先創建一個phonecatFilters模塊,並且將定制的過濾器checkmark注冊給這個模塊。

angular.module('phonecatFilters', []).filter('checkmark', function() {
  return function(input) {
    return input ? '\u2713' : '\u2718';
  };
});

我們的過濾器命名為checkmark。它的輸入要麼是true,要麼是false,並且我們返回兩個表示true或false的unicode字符(\u2713和\u2718)。

現在我們的過濾器准備好了,我們需要將我們的phonecatFilters模塊作為一個依賴,注冊到我們的主模塊phonecat上。

...
angular.module('phonecat', ['phonecatFilters']).
...

在AngularJS模板中使用過濾器的語法是:{{ expression | filter }}

因此,我們把過濾器應用到手機詳細信息模板中是這樣寫的:

...
    <dl>
      <dt>Infrared</dt>
        <dd>{{phone.connectivity.infrared | checkmark}}</dd>
      <dt>GPS</dt>
        <dd>{{phone.connectivity.gps | checkmark}}</dd>
    </dl>
...

這樣就實現了這樣的一個功能:手機詳細頁面原來是顯示“true”或者“false”來說明某個手機是否具有特定的特性。現在我們使用一個定制的過濾器來把那些文本串圖形化:√作為“true”;以及×作為“false”。也就說,在手機詳細頁面,true變成了√,false變成了×。

最後,我們讓手機詳細信息頁面上的手機圖片可以點擊。

手機詳細信息視圖展示了一幅當前手機的大號圖片,以及幾個小一點的縮略圖。我們實現當用戶點擊縮略圖就能把那張大的替換成用戶點擊的那張圖片。

 

...
function PhoneDetailCtrl($scope, $routeParams, $http) {
  $http.get('phones/' + $routeParams.phoneId + '.json').success(function(data) {
    $scope.phone = data;
    $scope.mainImageUrl = data.images[0];
  });

 $scope.setImage = function(imageUrl) {
    $scope.mainImageUrl = imageUrl;
  }
}

 

在PhoneDetailCtrl控制器中,我們創建了mainImageUrl模型屬性,並且把它的默認值設為第一個手機圖片的URL。

 

<img ng-src="{{mainImageUrl}}" class="phone">

...

<ul class="phone-thumbs">
  <li ng-repeat="img in phone.images">
    <img ng-src="{{img}}" ng-click="setImage(img)">
  </li>
</ul>
...

 

我們把大圖片的ngSrc指令綁定到mainImageUrl屬性上。

同時我們注冊一個ngClick處理器到縮略圖上。當一個用戶點擊縮略圖的任意一個時,這個處理器會使用setImage事件處理函數來把mainImageUrl屬性設置成選定縮略圖的URL。

這樣就輕易的實現了上面的需求。

對我們應用程序所做的最後一個改進是獲取數據的方式。我們可以用一種更簡單的方式來發送XHR請求,而不用去關心更底層的$http服務。

angular.module('phonecatServices', ['ngResource']).
    factory('Phone', function($resource){
      return $resource('phones/:phoneId.json', {}, {
        query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
      });
    });

我們使用模塊的API,通過它的工廠方法注冊了一個定制服務Phone。我們傳入服務的名字Phone和工廠函數。工廠函數和控制器構造函數差不多,它們都通過函數的參數聲明,來依賴服務。Phone服務聲明了它依賴於$resource服務。

我們需要在頁面上加載angularjs-resource.js這個文件,它包含了ngResource模塊以及其中的$resource服務:

...
<script src="lib/angular/angular-resource.js"></script>
...

$resource服務,用短短的幾行代碼就可以創建一個RESTful客戶端。我們的應用程序使用這個客戶端來代替底層的$http服務。AngularJS的$resource相比於$http更加適合於與RESTful數據源交互。

然後,我們需要把phonecatServices添加到phonecat的依賴數組裡。

...
angular.module('phonecat', ['phonecatFilters', 'phonecatServices']).
...

通過重構底層的$http服務,把它放在一個新的服務Phone中,我們可以大大簡化子控制器(PhoneListCtrl和PhoneDetailCtrl)。

 

...
function PhoneListCtrl($scope, Phone) {
  $scope.phones = Phone.query();
  $scope.orderProp = 'age';
}
//PhoneListCtrl.$inject = ['$scope', 'Phone'];
function PhoneDetailCtrl($scope, $routeParams, Phone) {
  $scope.phone = Phone.get({phoneId: $routeParams.phoneId}, function(phone) {
    $scope.mainImageUrl = phone.images[0];
  });
  $scope.setImage = function(imageUrl) {
    $scope.mainImageUrl = imageUrl;
  }
}
//PhoneDetailCtrl.$inject = ['$scope', '$routeParams', 'Phone'];

 

注意到,在PhoneListCtrl裡我們把:

$http.get('phones/phones.json').success(function(data) {
  $scope.phones = data;
});

換成了:

$scope.phones = Phone.query();

我們通過這條簡單的語句來查詢所有的手機。

另一個非常需要注意的是,在上面的代碼裡面,PhoneListCtrl控制器調用Phone服務的方法時,我們並沒有傳遞任何回調函數。盡管這看起來是同步返回的,其實根本就不是。同步返回的是一個“future”——一個對象,當XHR響應完成返回的時候會填充數據。鑒於AngularJS的數據綁定,我們可以使用future,並且把它綁定到我們的模板上。然後,當數據到達時,我們的視圖會自動更新。

但有的時候,單單依賴future對象和數據綁定不足以滿足我們的需求,所以在這些情況下,我們需要添加一個回調函數來處理服務器的響應。PhoneDetailCtrl控制器通過在一個回調函數中設置mainImageUrl就是一個解釋。

通過這四篇對angular.js的入門講解,我相信大家都angular有了初步的認識,接下來,我們將深入講解angular.js。

AngularJS權威教程 清晰PDF版  http://www.linuxidc.com/Linux/2015-01/111429.htm

希望你喜歡,並分享我的工作~帶你走近AngularJS系列

  1. 帶你走近AngularJS - 基本功能介紹 http://www.linuxidc.com/Linux/2014-05/102140.htm
  2. 帶你走近AngularJS - 體驗指令實例 http://www.linuxidc.com/Linux/2014-05/102141.htm
  3. 帶你走近AngularJS - 創建自定義指令 http://www.linuxidc.com/Linux/2014-05/102142.htm

如何在 AngularJS 中對控制器進行單元測試 http://www.linuxidc.com/Linux/2013-12/94166.htm

在 AngularJS 應用中通過 JSON 文件來設置狀態 http://www.linuxidc.com/Linux/2014-07/104083.htm

AngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htm

AngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交數據 http://www.linuxidc.com/Linux/2014-07/104402.htm

AngularJS 的詳細介紹:請點這裡
AngularJS 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved