04控制器-AngularJS基礎教程,-angularjs基礎教程

來源:互聯網
上載者:User

04控制器-AngularJS基礎教程,-angularjs基礎教程
0. 目錄

  • 目錄
  • 前言
  • 本文
    • 1 ng-controller
    • 2 構建模型-Constructing the model
    • 3 控制器作為屬性名稱-Controller as propertyName
    • 4 依賴注入-Dependency injection
      • 41 scope
    • 5 模型視圖控制器MVC-Model-view-controller
    • 6 函數-Functions
    • 7 回呼函數
    • 8 結論
  • 聲明

1. 前言

AngularJS是為了克服HTML在構建應用上的不足而設計的。HTML是一門很好的為靜態文本展示設計的聲明式語言,但要構建WEB應用的話它就顯得乏力了,所以AngularJS做了一些工作來來解決靜態網頁技術在構建Live App上的不足。

AngularJS的初衷是為了簡化web APP開發,精髓是簡單。但是國內外有很多AngularJS的教程,都著重講AngularJS的強大之處,從而增加了AngularJS學習的難度,本教程試圖用通俗的語言講解最為基礎最為實用的內容,簡化學習進程、降低學習難度是本教程的初衷。

本系列教程以翻譯Chris SmithAngualr Basics為梗概,融合博主自己的理解,為大家提供一個簡單明了的學習教程。

本文為系列教程第4篇控制器,翻譯自Controllers

2.本文

在前一章中,我讓您勒住韁繩,只把Angular作為HTML的功能擴充,當然Angular遠不止這些,事實上通過Javascript實現自訂行為是每個Angular項目的必要部分。如果您在前一章中抱有編程的衝動,你的耐心應該得到嘉獎,現在該寫點Javascript了。

最常見的給Angular view(視圖)增加控制的方法是通過控制器(controller),最簡單的書寫控制器的方法是通過書寫建構函式的方式。為了協助大家理解整個過程,我們通過一個非常簡單的控制器來示範一下(非常簡單,甚至連hello world也沒有,就是個空的controller)。

下面是我們的控制器(controller)。

/* empty-controller.js */function EmptyController() {};

當然,我們必須把angular類庫匯入進來,同時利用ng-app命令告訴html,我們將在這裡使用angular。

<!-- index.html --><!-- 匯入類庫 --><script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script><!--google被牆,大家可以用國內的cdn--><script src="//apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script><!-- ng-app告訴html,我們將使用angular --><body ng-app="app">  <!-- Other examples to be inserted here. --></body>

控制器可以在全域範圍內使用建構函式的方式進行定義,本章就是使用這種方式。在Angular1.3以前版本中可以直接使用簡單方式,不過現在需要進行一些配置,建立一個命名的應用模組(named application module)。如何使用Angular模組我們會在接下來的模組、依賴注入和服務章節中詳細講解,現在,你只需要使用下面的案例作為樣板檔案(boilerplate)即可。

/* module.js */angular.module('app', []);angular.module('app').config(['$controllerProvider', function($controllerProvider) {  $controllerProvider.allowGlobals();}]);

現在我們先不管這些,我們來試試什麼都不乾的控制器(noop controller)。

2.1 ng-controller

像通常那樣,使用指令(directive)可以搞定這些,使用ng-controller指令可以通過它的名字找到並調用控制器函數。

<!-- empty-controller.html --><p ng-controller="EmptyController"></p>

當然,正如您所想,它將調用我們上面定義的那個EmptyController建構函式,nothing to do。接下來,我們來研究下什麼是控制器?如何使用?

2.2 構建模型-Constructing the model

在官方指南的核心概覽部分把Angular的工作描述為“將變數和函數功能傳遞給運算式和指令”,這裡的函數功能指回呼函數,我們稍候重點講解,現在先來瞭解一下變數初始化模型準備

明白Angular模型就是運算式範圍可以讀取的一些普通Javascript代碼之後,準備模型就是小意思了。普通javascript代碼?是的,我們可以書寫普通js代碼,讓我們給空的控制器增加一個string屬性。

/* message-controller-as.js */function MessageController() {  this.message = "This is a model.";}

簡單吧!成功了嗎?我們已經成功的建立了一個模型?是也不是?

答案是幾乎。當我們在試圖範圍中獲得message屬性之後,它就是一個模型了。完成這個任務的一種方法,就是讓整個控制器作為scope中的一個屬性,聽起來很玄乎吧,當你瞭解了文法的秘密,一切將變得非常簡單。

2.3 控制器作為屬性名稱-Controller as propertyName

正像官方API描述的那樣,ng-controller可以接受controll as propertyName運算式作為參數,注意只有Angular1.2以後版本才可使用本特性。

<!-- message-controller.html --><p ng-controller="MessageController as controller">  {{controller.message}}</p>

編譯結果為:This is a model.

這樣,我們就是用controller準備好了模型資料。

儘管這種給引用附加屬性的方式直接明了,但是“把整個controller暴露給視圖”容易給人誤解,讓人感覺控制器是模型的一部分,而實際上,控制器的作用僅僅是為模型準備資料。當你僅僅滿足用戶端需求,不考慮更多需求時,測試和調試都會非常簡單。而且,這種方式會為視圖代碼帶來雜訊,因為所有的屬性必須通過控制器的引用訪問。視圖代碼通常是一個web應用雜訊要求最苛刻的地區,它可能是一瞥之後出現理解困難的第一個地方。最後,控制器(controller)和範圍(scope)並進工作,從教學角度來說,明晰scope的引用並精細控制它,會非常有用,通過這些控制,我們可以明確地暴露我們想要暴露給視圖的部分。因此,本書更傾向於這種能夠明確管理scope對象的控制器樣式。

那麼問題來了,我們如何獲得這個scope對象的引用?使用new運算子傳建一個?還是從某個地方請求?

2.4 依賴注入-Dependency injection

不是的。我們通過依賴注入獲得它。你可能已經注意到我並沒有展示執行個體化控制器的代碼,例如var controller=new MessageController();那麼,誰建立了視圖中使用的控制器?

當然是Angular。Angular是一個控制反轉(Inversion of Control,英文縮寫為IoC)容器,可以管理應用組件的生存周期。當需要一個新的控制器或者新的組件時,Angular會建立一個。這可以節省時間,而且更重要的是,可以讓Angular給組件注入資源、依賴性等。

2.4.1 $scope

作為一個通過依賴注入架構管理的組件,控制器只需要通過一個參數$scope即可。參數的名字非常關鍵,實際上,如果你壓縮了你的Javascript原始碼,你會破壞依賴注入機制(無須擔心,有一個變通方案,我們會在依賴注入章節詳解)。

/* message-controller-scope.js */function MessageController($scope) {  $scope.message = "This is a model.";}

通過給建構函式增加$scope參數,我們通知Angualr我們需要一個視圖範圍的引用。可以再簡單一些嗎?現在我們可以不在控制器裡聲明message屬性,而是直接在scope中定義它。

在模板中,我們從ng-controller指令中移除as controllercontroller.message變成message,這個是我們附加到scope的唯一的屬性。

<!-- message-controller-scope.html --><p ng-controller="MessageController">  {{message}}</p>

編譯結果為:This is a model.

儘管兩種方式都可以正常工作,本書更多使用指定明確的$scope的方式。依賴注入是Angualr的特色,所以我們要儘可能的熟悉它。

2.5 模型視圖控制器MVC-Model-view-controller

官方指南的控制器定義中也涉及到向視圖暴露”功能性”。在我們討論這個問題之前,我覺得有必要花點時間討論下Angular控制器與經典MVC模式的不同。

根據維基百科model-view-controller (MVC)的解釋,控制器“mediates input, converting it to commands for the model or view”。但是很難在Angular範圍內理解“commands for the model or view”,因為Angular的MVC模型非常簡單,採用僅有規則沒有邏輯的貧血模型。截至目前,Angular最流行的方法是,把所有的商務邏輯(域邏輯)放到控制器裡,換句話說,Angular應用趨向於瘦模型和胖控制器( skinny models and fat controllers)。

如果您熟悉模式,例如富領域模型(rich domain model)、瘦模型胖控制器(Skinny Controller, Fat Model)等,我想你會發現Angular的方法有點倒退。我想這個只可能是優先順序問題,在用戶端編程中,兩者之間存在著顯著差異,一邊是聲明式的、DOM為中心的視圖代碼,另一邊是命令式的、資料驅動的JS代碼來處理商務邏輯和應用程式基底礎。這是巨大的成功,我很高興類似於Angular之類的架構關注這些。一段時間之後,商務邏輯從控制器中分離開來可能佔有更高的優先順序,我們可能看到富模型(richer models)的趨勢。

2.6 函數-Functions

讓我們書寫一個包含簡單函數的控制器,體驗下在視圖中調用該函數。你可能會想起,在上一章中我們說過,Angular不允許在視圖中聲明函數。

下面的控制器把一個函數指定給scope的一個屬性。

/* count-controller.js */function CountController($scope) {  $scope.count = function() { return 12; }}

運算式裡調用函數方法和普通js代碼沒有區別,使用{{ }}

<!--count-controller.html--><p ng-controller="CountController">  There are {{count()}} months in a year.</p>

編譯結果為: There are 12 months in a year.

注意,函數不是簡單地調用和忘記,而是綁定在模型上。 什麼意思? 你Angular的綁定特性(你可能會逐步舉得理所當然),意味著Angular不但會在視圖第一次渲染時調用該函數,而且會在相關模型改變時調用。為了讓大家明白工作原理,我們需要一個使用模型資料的函數,下面的求和函數使用兩個scope中聲明的模型屬性,operand1operand2。Angular將會在任意屬性發生改變時調用函數和渲染結果。

/* addition-controller.js */function AdditionController($scope) {  $scope.operand1 = 0;  $scope.operand2 = 0;  $scope.add = function() {    return $scope.operand1 + $scope.operand2;  }  $scope.options = [0,1,2,3,4];}

因為我們已經多次使用input指令,這次讓我們用Angular的select指令改變模型資料。您可能已經注意到,上面代碼的最後一行的$scope.options,我們接下來使用ng-options指令把數組資料放置到select裡面。x for x in options這個寫法感覺有點廢話,無論如何記住它吧()。

<!-- addition-controller.html --><p ng-controller="AdditionController">  <select ng-model="operand1" ng-options="x for x in options"></select>  + <select ng-model="operand2" ng-options="x for x in options"></select>  = {{add()}}</p>

編譯之後結果如下面動圖所示。

不錯吧!但是,如果你不想使用operand1和operand2而想使用屬性,我們可以在泛化性上做些改善。擺脫您的重構手冊、擼起袖子進行一些參數抽象。

/* addition-controller-params.js */function AdditionController($scope) {  $scope.number = 2;  $scope.add = function(operand1, operand2) {    return operand1 + operand2;  }}

在運算式內部,函數參數可以是屬性,也可以是字面值。

<!-- addition-controller-params.html --><p ng-controller="AdditionController">  {{add(number, 2)}} is not the same as {{add(number, "2")}}  <br>  2 + 2 + 2 + 2 = {{add(2, add(2, add(2, 2)))}}</p>

編譯結果為:
4 is not the same as 22
2 + 2 + 2 + 2 = 8

接下來,我們通過一個回呼函數來處理使用者行為。

2.7 回呼函數

上一章曾經有一個案例,利用ng-click切換boolean值,在ng-init指令中初始化authorized,利用ng-click="authorized = !authorized實現簡單、行內回調,讓我們把該案例做個改進,把模型初始化、切換logic變數都放到控制器裡去。

/* auth-controller.js */function AuthController($scope) {  $scope.authorized = true;  $scope.toggle = function() {    $scope.authorized = !$scope.authorized  };}

現在toggle是一個範圍中的函數,ng-click的參數看起來像個函數調用toggle()。 它不是真正的函數調用, 只是一個使用者單擊時會執行的字串而已。

<!-- auth-controller.html --><div ng-controller="AuthController">  <p>    The secret code is    <span ng-show="authorized">0123</span>    <span ng-hide="authorized">not for you to see</span>  </p>  <input class="btn btn-xs btn-default" type="button" value="toggle" ng-click="toggle()"></div>

編譯結果如下動圖所示。

案例依然正常工作,而且在一個更好的地方實現了邏輯切換。為什麼更好呢?一個很好的問題。在控制器內處理使用者行為的好處在於,當我們實現更為複雜的使用者行為時可以保證代碼清晰可讀,例如處理來自遠程伺服器的非同步模型資料(如果您迫不及待的想瞭解這部分知識,請跳至本書的http部分)。

2.8 結論

我們在Angular的使用中引入了javascript,控制器(controller)在MVC模式中扮演者為視圖準備資料的功能,它通過在scope對象上聲明屬性,實現該功能。下一章中,我們將詳細介紹scope對象,瞭解它如何組織成一個體系與應用的DOM結構匹配。

3.聲明

前端開發whqet,關注前端開發,分享相關資源。csdn專家部落格,王海慶希望能對您有所協助,限於作者水平有限,出錯難免,歡迎拍磚!
歡迎任何形式的轉載,煩請註明裝載,保留本段文字。
本文原文連結,http://blog.csdn.net/whqet/article/details/44698845
歡迎大家訪問獨立部落格http://whqet.github.io

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.