国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
AngularJS自學(xué)之路(三)
2015-04-07 14:20 163人閱讀 評(píng)論(0) 收藏 舉報(bào)

控制器

控制器在AngularJS中的作用是增強(qiáng)視圖。
AngularJS中的控制器是一個(gè)函數(shù),用來(lái)向視圖的作用域中添加額外的功能。我們用它來(lái)給作用域?qū)ο笤O(shè)置初始狀態(tài),并添加自定義行為。
當(dāng)我們?cè)陧?yè)面上創(chuàng)建一個(gè)新的控制器時(shí),AngularJS會(huì)生成并傳遞一個(gè)新的$scope給這個(gè)控制器??梢栽谶@個(gè)控制器里初始化scope。由于AngularJS會(huì)負(fù)責(zé)處理控制器的實(shí)例化過(guò)程,我們只需編寫(xiě)構(gòu)造函數(shù)即可。下面的例子展示了控制器初始化:

function FirstController($scope) {$scope.message = "hello";}
  • 1
  • 2
  • 3

細(xì)心的讀者會(huì)發(fā)現(xiàn),我們是在全局作用域中創(chuàng)建的這個(gè)函數(shù)。這樣做并不合適,因?yàn)闀?huì)污染全局命名空間。更合理的方式是創(chuàng)建一個(gè)模塊,然后在模塊中創(chuàng)建控制器,如下所示:

var app = angular.module('app', []);app.controller('FirstController', function($scope) {$scope.message = "hello";});
  • 1
  • 2
  • 3
  • 4

只需創(chuàng)建控制器作用域中的函數(shù),就能創(chuàng)建可以在視圖中使用的自定義操作。很幸運(yùn),AngularJS允許我們?cè)谝晥D中像調(diào)用普通數(shù)據(jù)一樣調(diào)用$scope上的函數(shù)。

用內(nèi)置指令ng-click可以將按鈕、鏈接等其他任何DOM元素同點(diǎn)擊事件進(jìn)行綁定。ng-click指令將瀏覽器中的mouseup事件,同設(shè)置在DOM元素上的事件處理程序綁定在一起(例如,當(dāng)瀏覽器在某個(gè)DOM元素上觸發(fā)了點(diǎn)擊事件,函數(shù)就會(huì)被調(diào)用)。和前面的例子類(lèi)似,綁定看起來(lái)是這樣的:

<div ng-controller="FirstController"><h4>The simplest adding machine ever</h4><button ng-click="add(1)" class="button">Add</button><a ng-click="subtract(1)" class="button alert">Subtract</a><h4>Current count: {{ counter }}</h4></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

按鈕和鏈接都被綁定在了內(nèi)部$scope的一個(gè)操作上,當(dāng)點(diǎn)擊任何一個(gè)元素時(shí)AngularJS都會(huì)調(diào)用相應(yīng)的方法。注意,當(dāng)設(shè)置調(diào)用哪個(gè)函數(shù)時(shí),會(huì)同時(shí)用括號(hào)傳遞一個(gè)參數(shù)(add(1))。
下面給FirstController添加一個(gè)操作:

app.controller('FirstController', function($scope) {$scope.counter = 0;$scope.add = function(amount) { $scope.counter += amount; };$scope.subtract = function(amount) { $scope.counter -= amount; };});
  • 1
  • 2
  • 3
  • 4
  • 5

控制器可以將與一個(gè)獨(dú)立視圖相關(guān)的業(yè)務(wù)邏輯封裝在一個(gè)獨(dú)立的容器中。盡可能地精簡(jiǎn)控制器是很好的做法。作為AngularJS開(kāi)發(fā)者,使用依賴(lài)注入來(lái)訪(fǎng)問(wèn)服務(wù)可以實(shí)現(xiàn)這個(gè)目的。

AngularJS同其他JavaScript框架最主要的一個(gè)區(qū)別就是,控制器并不適合用來(lái)執(zhí)行DOM操作、格式化或數(shù)據(jù)操作,以及除存儲(chǔ)數(shù)據(jù)模型之外的狀態(tài)維護(hù)操作。它只是視圖和$scope之間的橋梁。

控制器嵌套(作用域包含作用域)

默認(rèn)情況下,AngularJS在當(dāng)前作用域中無(wú)法找到某個(gè)屬性時(shí),便會(huì)在父級(jí)作用域中進(jìn)行查找。如果AngularJS找不到對(duì)應(yīng)的屬性,會(huì)順著父級(jí)作用域一直向上尋找,直到抵達(dá)$rootScope為止。如果在rootScope中也找不到,程序會(huì)繼續(xù)運(yùn)行,但視圖無(wú)法更新。

通過(guò)例子來(lái)看一下這個(gè)行為。創(chuàng)建一個(gè)ParentController,其中包含一個(gè)user對(duì)象,再創(chuàng)建一個(gè)ChildController來(lái)引用這個(gè)對(duì)象:

app.controller('ParentController', function($scope) {$scope.person = {greeted: false};});app.controller('ChildController', function($scope) {$scope.sayHello = function() {$scope.person.name = 'Ari Lerner';};});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果我們將ChildController置于ParentController內(nèi)部,那ChildController的$scope對(duì)象的父級(jí)作用域就是ParentController的scope對(duì)象。根據(jù)原型繼承的機(jī)制,我們可以在子作用域中訪(fǎng)問(wèn)ParentController的scope對(duì)象。

例如,我們可以在ChildController的DOM元素中訪(fǎng)問(wèn)定義在ParentController中的person對(duì)象

<div ng-controller="ParentController"><div ng-controller="ChildController"><a ng-click="sayHello()">Say hello</a></div>{{ person }}</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我們看到,點(diǎn)擊按鈕時(shí),可以在ChildController中訪(fǎng)問(wèn)ParentController中$scope.person的值,就好像person對(duì)象定義在ChildController的scope中一樣。

控制器應(yīng)該盡可能保持短小精悍,而在控制器中進(jìn)行DOM操作和數(shù)據(jù)操作則是一個(gè)不好的實(shí)踐。

設(shè)計(jì)良好的應(yīng)用會(huì)將復(fù)雜的邏輯放到指令和服務(wù)中。通過(guò)使用指令和服務(wù),我們可以將控制器重構(gòu)成一個(gè)輕量且更易維護(hù)的形式
簡(jiǎn)潔的控制器:

angular.module('myApp', []).controller('MyController', function($scope,UserSrv) {// 內(nèi)容可以被指令控制$scope.onLogin = function(user) {UserSrv.runLogin(user);};});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

表達(dá)式

前面已經(jīng)見(jiàn)過(guò)使用表達(dá)式的示例。用{{ }}符號(hào)將一個(gè)變量綁定到$scope上的寫(xiě)法本質(zhì)上就是一個(gè)表達(dá)式:{{ expression }}。當(dāng)用watch進(jìn)行監(jiān)聽(tīng)時(shí),AngularJS會(huì)對(duì)表達(dá)式或函數(shù)進(jìn)行運(yùn)算。
表達(dá)式和eval(javascript)非常相似,但是由于表達(dá)式由AngularJS來(lái)處理,它們有以下顯著不同的特性:

  1. 所有的表達(dá)式都在其所屬的作用域內(nèi)部執(zhí)行,并有訪(fǎng)問(wèn)本地$scope的權(quán)限;
  2. 如果表達(dá)式發(fā)生了TypeError和ReferenceError并不會(huì)拋出異常;
  3. 不允許使用任何流程控制功能(條件控制,例如if/else);
  4. 可以接受過(guò)濾器和過(guò)濾器鏈。

對(duì)表達(dá)式進(jìn)行的任何操作,都會(huì)在其所屬的作用域內(nèi)部執(zhí)行,因此可以在表達(dá)式內(nèi)部調(diào)用那些限制在此作用域內(nèi)的變量,并進(jìn)行循環(huán)、函數(shù)調(diào)用、將變量應(yīng)用到數(shù)學(xué)表達(dá)式中等操作。

解析AngularJS 表達(dá)式

盡管AngularJS會(huì)在運(yùn)行$digest循環(huán)的過(guò)程中自動(dòng)解析表達(dá)式,但有時(shí)手動(dòng)解析表達(dá)式也是非常有用的。

AngularJS通過(guò)$parse這個(gè)內(nèi)部服務(wù)來(lái)進(jìn)行表達(dá)式的運(yùn)算,這個(gè)服務(wù)能夠訪(fǎng)問(wèn)當(dāng)前所處的作用域。

將$parse服務(wù)注入到控制器中,然后調(diào)用它就可以實(shí)現(xiàn)手動(dòng)解析表達(dá)式。舉例來(lái)說(shuō),如果頁(yè)面上有一個(gè)輸入框綁定到了expr變量上,如下所示:

<div ng-controller="MyController"><input ng-model="expr" type="text" placeholder="Enter an expression" /><h2>{{ parseValue }}</h2></div>
  • 1
  • 2
  • 3
  • 4
  • 5

我們可以在MyController中給expr這個(gè)表達(dá)式設(shè)置一個(gè)$watch并解析它:

angular.module("myApp", []).controller('MyController',function($scope,$parse) {$scope.$watch('expr', function(newVal, oldVal, scope) {if (newVal !== oldVal) {// 用該表達(dá)式設(shè)置parseFunvar parseFun = $parse(newVal);// 獲取經(jīng)過(guò)解析后表達(dá)式的值$scope.parsedValue = parseFun(scope);}});});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

插值字符串

在AngularJS中,我們的確有手動(dòng)運(yùn)行模板編譯的能力。例如,插值允許基于作用域上的某個(gè)條件實(shí)時(shí)更新文本字符串。

要在字符串模板中做插值操作,需要在你的對(duì)象中注入$interpolate服務(wù)。在下面的例子中,我們將會(huì)將它注入到一個(gè)控制器中:

angular.module('myApp', []).controller('MyController',function($scope, $interpolate) {// 我們同時(shí)擁有訪(fǎng)問(wèn)$scope和$interpolate服務(wù)的權(quán)限});
  • 1
  • 2
  • 3
  • 4

$interpolate服務(wù)是一個(gè)可以接受三個(gè)參數(shù)的函數(shù),其中第一個(gè)參數(shù)是必需的。

  1. text(字符串):一個(gè)包含字符插值標(biāo)記的字符串。
  2. mustHaveExpression(布爾型):如果將這個(gè)參數(shù)設(shè)為true,當(dāng)傳入的字符串中不含有表達(dá)式時(shí)會(huì)返回null。
  3. trustedContext(字符串):AngularJS會(huì)對(duì)已經(jīng)進(jìn)行過(guò)字符插值操作的字符串通過(guò)$sec.getTrusted()方法進(jìn)行嚴(yán)格的上下文轉(zhuǎn)義。

$interpolate服務(wù)返回一個(gè)函數(shù),用來(lái)在特定的上下文中運(yùn)算表達(dá)式。
設(shè)置好這些參數(shù)后,就可以在控制器中進(jìn)行字符插值的操作了。例如,假設(shè)我們希望可以在電子郵件的正文中進(jìn)行實(shí)時(shí)編輯,當(dāng)文本發(fā)生變化時(shí)進(jìn)行字符插值操作并將結(jié)果展示出來(lái)。

<div ng-controller="MyController"><input ng-model="to"type="email"placeholder="Recipient" /><textarea ng-model="emailBody"></textarea><pre>{{ previewText }}</pre></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由于控制器內(nèi)部設(shè)置了一個(gè)需要每次變化都重新進(jìn)行字符插值的自定義輸入字段,因此需要設(shè)置一個(gè)$watch來(lái)監(jiān)聽(tīng)數(shù)據(jù)的變化。

簡(jiǎn)而言之,$watch函數(shù)會(huì)監(jiān)視scope上的某個(gè)屬性。只要屬性發(fā)生變化就會(huì)調(diào)用對(duì)應(yīng)的函數(shù)??梢允褂脀atch函數(shù)在scope上某個(gè)屬性發(fā)生變化時(shí)直接運(yùn)行一個(gè)自定義函數(shù)。

在控制器中,我們?cè)O(shè)置了$watch來(lái)監(jiān)視郵件正文的變化,并將emailBody屬性的值進(jìn)行字符插值后的結(jié)果賦值給previewText屬性。

angular.module('myApp', []).controller('MyController', function($scope, $interpolate) {// 設(shè)置監(jiān)聽(tīng)$scope.$watch('emailBody', function(body) {if (body) {var template = $interpolate(body);$scope.previewText =template({to: $scope.to});}};});在
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

現(xiàn)在,在{{ previewText }}內(nèi)部的文本中可以將{{ to }}當(dāng)做一個(gè)變量來(lái)使用,并對(duì)文本的變化進(jìn)行實(shí)時(shí)更新。

用startSymbol()方法可以修改標(biāo)識(shí)開(kāi)始的符號(hào)。這個(gè)方法接受一個(gè)參數(shù)。

用endSymbol()方法可以修改標(biāo)識(shí)結(jié)束的符號(hào)。這個(gè)方法也接受一個(gè)參數(shù)。

如果要修改這兩個(gè)符號(hào)的設(shè)置,需要在創(chuàng)建新模塊時(shí)將$interpolateProvider注入進(jìn)去。

angular.module('emailParser', []).config(['$interpolateProvider', function($interpolateProvider) {$interpolateProvider.startSymbol('__');$interpolateProvider.endSymbol('__');}]).factory('EmailParser', ['$interpolate', function($interpolate) {// 處理解析的服務(wù)return {parse: function(text, context) {var template = $interpolate(text);return template(context);}};}]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

現(xiàn)在,我們已經(jīng)創(chuàng)建了一個(gè)模塊,可以將它注入到應(yīng)用中,并在郵件正文的文本中運(yùn)行這個(gè)郵件解析器:

angular.module('myApp', ['emailParser']).controller('MyController', ['$scope', 'EmailParser',function($scope, EmailParser) {// 設(shè)置監(jiān)聽(tīng)$scope.$watch('emailBody', function(body) {if (body) {$scope.previewText = EmailParser.parse(body, {to: $scope.to});}});}]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

現(xiàn)在用自定義的 __ 符號(hào)取代默認(rèn)語(yǔ)法中的 {{ }} 符號(hào)來(lái)請(qǐng)求插值文本。
由于我們將表達(dá)式開(kāi)始和結(jié)束的符號(hào)都設(shè)置成了__,因此需要將HTML修改成用這個(gè)符號(hào)取代{{ }}的版本,

<div id="emailEditor"><input ng-model="to"type="email"placeholder="Recipient" /><textarea ng-model="emailBody"></textarea></div><div id="emailPreview"><pre>__ previewText __</pre></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
AngularJS開(kāi)發(fā)指南17:Controller組件
AngularJS1:directive和controller如何通信
跟我學(xué)AngularJs:AngularJs內(nèi)置指令大全
AngularJS快速入門(mén)指南18:Application   是時(shí)候創(chuàng)建一個(gè)真正的AngularJS單頁(yè)面應(yīng)用程序了(SPA)。 一個(gè)AngularJS應(yīng)用程序示例   你已經(jīng)了解了足夠多的內(nèi)容
AngularJS進(jìn)階(九)控制器controller之間如何通信
【AngularJS】作用域詳解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服