中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

詳解JavaScript的AngularJS框架中的作用域與數據綁定
來源:易賢網 閱讀:1050 次 日期:2016-08-02 15:30:03
溫馨提示:易賢網小編為您整理了“詳解JavaScript的AngularJS框架中的作用域與數據綁定”,方便廣大網友查閱!

AngularJS 簡介

AngularJS 是由 Google 發起的一款開源的前端 MVC 腳本框架,既適合做普通 WEB 應用也可以做 SPA(單頁面應用,所有的用戶操作都在一個頁面中完成)。與同為 MVC 框架的 Dojo 的定位不同,AngularJS 在功能上更加輕量,而相比于 jQuery,AngularJS 又幫您省去了許多機械的綁定工作。在一些對開發速度要求高,功能模塊不需要太豐富的非企業級 WEB 應用上,AngularJS 是一個非常好的選擇。AngularJS 最為復雜同時也是最強大的部分就是它的數據綁定機制,這個機制幫助我們能更好的將注意力集中在數據的模型建立和傳遞上,而不是對底層的 DOM 進行低級的操作。

AngularJS 作用域

基于 jQuery 的傳統 WEB 應用中,為了監聽用戶的輸入等行為,需要為每一個 DOM 元素設置一個監聽方法,也即是監聽 DOM 上發生的各類事件,然后由 jQuery 做出回應并展示在頁面上。這種方法簡便直觀,但是一旦 WEB 應用變得龐大而且復雜,那么監聽代碼就顯得非常的機械而且冗余,更可怕的是,如果對于 DOM 的事件監聽沒有做好管理,那么很容易出現瀏覽器資源的泄露。

針對以上所暴露的問題,AngularJS 用一系列指令來代替 jQuery 的事件綁定代碼。為了能夠組織好各類指令之間的協調工作而不出現數據混亂,AngularJS 在模型層上引申出作用域的概念,以配合控制器來實現對視圖層的展現工作。

作用域(Scope)

AngularJS 中,作用域是一個指向應用模型的對象,它是表達式的執行環境。作用域有層次結構,這個層次和相應的 DOM 幾乎是一樣的。作用域能監控表達式和傳遞事件。

在 HTML 代碼中,一旦一個 ng-app 指令被定義,那么一個作用域就產生了,由 ng-app 所生成的作用域比較特殊,它是一個根作用域($rootScope),它是其他所有$Scope 的最頂層。

清單 1. 生成根作用域

<html>

 <head><script src="angular.min.js"></script></head>

 <body data-ng-app="app">...</body>

</html>

除了用 ng-app 指令可以產生一個作用域之外,其他的指令如 ng-controller,ng-repeat 等都會產生一個或者多個作用域。此外,還可以通過 AngularJS 提供的創建作用域的工廠方法來創建一個作用域。這些作用域都擁有自己的繼承上下文,并且根作用域都為$rootScope。

在生成一個作用域之后,在編寫 AngularJS 代碼時,$scope 對象就代表了這個作用域的數據實體,我們可以在$scope 內定義各種數據類型,之后可以直接在 HTML 中以 {{變量名}} 方式來讓 HTML 訪問到這個變量,代碼如下:

清單 2. 簡單的數據綁定

<script>

angular.module('app', [])

 .controller("ctrl", function ($scope) {

 $scope.btns = {

 ibm : 'ibm'

 };

 });

</script>

</head>

<body data-ng-app="app" >

 <div data-ng-controller="ctrl">

 <button>{{btns.ibm}}</button>

 </div>

</body>

這就是 AngularJS 中最簡單的數據綁定方式,同時也是應用最為廣泛的數據綁定方式。

繼承作用域(Inherited Scope)

AngularJS 在創建一個作用域時,會檢索上下文,如果上下文中已經存在一個作用域,那么這個新創建的作用域就會以 JavaScript 原型繼承機制繼承其父作用域的屬性和方法(有個例外是孤立作用域,下文討論)。

一些 AngularJS 指令會創建新的子作用域,并且進行原型繼承: ng-repeat、ng-include、ng-switch、ng-view、ng-controller, 用 scope: true 和 transclude: true 創建的 directive。

以下 HTML 中定義了三個作用域,分別是由 ng-app 指令所創建的$rootScope,parentCtrl 和 childCtrl 所創建的子作用域,這其中 childCtrl 生成的作用域又是 parentCtrl 的子作用域。

清單 3. 作用域的繼承實例

<body data-ng-app="app">

 <div data-ng-controller="parentCtrl">

<input data-ng-model="args">

<div data-ng-controller="childCtrl">

 <input data-ng-model="args">

</div>

 </div>

</body>

繼承作用域符合 JavaScript 的原型繼承機制,這意味著如果我們在子作用域中訪問一個父作用域中定義的屬性,JavaScript 首先在子作用域中尋找該屬性,沒找到再從原型鏈上的父作用域中尋找,如果還沒找到會再往上一級原型鏈的父作用域尋找。在 AngularJS 中,作用域原型鏈的頂端是$rootScope,AnguarJS 將會尋找到$rootScope 為止,如果還是找不到,則會返回 undefined。

我們用實例代碼說明下這個機制。首先,我們探討下對于原型數據類型的作用域繼承機制:

清單 4. 作用域繼承實例-原始類型數據繼承

<script type="text/javascript">

 angular.module('app', [])

 .controller('parentCtrl', ['$scope', function($scope) {

 $scope.args = 'IBM DeveloperWorks';

 }])

 .controller('childCtrl', ['$scope', function($scope) { 

 }]);

</script>

<body data-ng-app="app">

 <div data-ng-controller="parentCtrl">

 <input data-ng-model="args">

<div data-ng-controller="childCtrl">

 <input data-ng-model="args">

</div>

 </div>

</body>

運行頁面,我們得到以下的結果:

圖 1. 頁面運行結果。

名單

這個結果我們非常好理解,雖然在 childCtrl 中沒有定義具體的 args 屬性,但是因為 childCtrl 的作用域繼承自 parentCtrl 的作用域,因此,AngularJS 會找到父作用域中的 args 屬性并設置到輸入框中。而且,如果我們在第一個輸入框中改變內容,內容將會同步的反應到第二個輸入框:

圖 2. 改變第一個輸入框的內容后頁面運行結果

名單

假如我們修改第二個輸入框的內容,此時會發生什么事情呢?答案是第二個輸入框的內容從此將不再和第一個輸入框的內容保持同步。在改變第二個輸入框的內容時,因為 HTML 代碼中 model 明確綁定在 childCtrl 的作用域中,因此 AngularJS 會為 childCtrl 生成一個 args 原始類型屬性。這樣,根據 AngularJS 作用域繼承原型機制,childCtrl 在自己的作用域找得到 args 這個屬性,從而也不再會去尋找 parentCtrl 的 args 屬性。從此,兩個輸入框的內容所綁定的屬性已經是兩份不同的實例,因此不會再保持同步。

圖 3. 改變第二個輸入框的內容后頁面運行結果

名單

假如我們將代碼做如下修改,結合以上兩個場景,思考下會出現怎樣的結果?

清單 5. 作用域繼承實例-對象數據繼承

<script type="text/javascript">

angular.module('app', [])

 .controller('parentCtrl', ['$scope', function($scope) {

 $scope.args = {};

 $scope.args.content = 'IBM DeveloperWorks';

}])

.controller('childCtrl', ['$scope', function($scope) { 

}]);

</script>

<body data-ng-app="app">

 <div data-ng-controller="parentCtrl">

 <input data-ng-model="args.content">

 <div data-ng-controller="childCtrl">

 <input data-ng-model="args.content">

 </div>

 </div>

</body>

答案是無論改變任何一個輸入框的內容,兩者的內容始終同步。

根據 AngularJS 的原型繼承機制,如果 ng-model 綁定的是一個對象數據,那么 AngularJS 將不會為 childCtrl 創建一個 args 的對象,自然也不會有 args.content 屬性。這樣,childCtrl 作用域中將始終不會存在 args.content 屬性,只能從父作用域中尋找,也即是兩個輸入框的的變化其實只是在改變 parentCtrl 作用域中的 args.content 屬性。因此,兩者的內容始終保持同步。

我們再看一個例子,這次請讀者自行分析結果。

清單 6. 作用域繼承實例-不再訪問父作用域的數據對象。

<script type="text/javascript">

 angular.module('app', [])

 .controller('parentCtrl', ['$scope', function($scope) {

 $scope.args = {};

 $scope.args.content = 'IBM DeveloperWorks';

}])

.controller('childCtrl', ['$scope', function($scope) {

 $scope.args = {}; 

 $scope.args.content = 'IBM DeveloperWorks';

}]);

</script>

<body data-ng-app="app">

 <div data-ng-controller="parentCtrl">

 <input data-ng-model="args.content">

 <div data-ng-controller="childCtrl">

 <input data-ng-model="args.content">

 </div>

 </div>

</body>

答案是兩個輸入框的內容永遠不會同步。

孤立作用域(Isolate Scope)

孤立作用域是 AngularJS 中一個非常特殊的作用域,它只在 directive 中出現。在對 directive 的定義中,我們添加上一個 scope:{} 屬性,就為這個 directive 創建出了一個隔離作用域。

清單 7. directive 創建出一個孤立作用域

angular.module('isolate', []).directive("isolate", function () {

 return {

 scope : {},

 };

})

孤立作用域最大的特點是不會原型繼承其父作用域,對外界的父作用域保持相對的獨立。因此,如果在定義了孤立作用域的 AngularJS directive 中想要訪問其父作用域的屬性,則得到的值為 undefined。代碼如下:

清單 8. 孤立作用域的隔離性

<script type="text/javascript">

 angular.module('app', [])

 .controller('ctrl', ['$scope', function($scope) {

 $scope.args = {};

 }])

 .directive("isolateDirective", function () {

 return {

 scope : {},

 link : function($scope, $element, $attr) {

 console.log($scope.$args); //輸出 undefined

 }

 };

});

</script>

<body data-ng-app="app">

 <div data-ng-controller="ctrl">

 <div data-isolate-directive></div>

 </div>

</body>

上面的代碼中通過在 directive 中聲明了 scope 屬性從而創建了一個作用域,其父作用域為 ctrl 所屬的作用域。但是,這個作用域是孤立的,因此,它訪問不到父作用域的中的任何屬性。存在這樣設計機制的好處是:能夠創建出一些列可復用的 directive,這些 directive 不會相互在擁有的屬性值上產生串擾,也不會產生任何副作用。

AngularJS 孤立作用域的數據綁定

在繼承作用域中,我們可以選擇子作用域直接操作父作用域數據來實現父子作用域的通信,而在孤立作用域中,子作用域不能直接訪問和修改父作用域的屬性和值。為了能夠使孤立作用域也能和外界通信,AngularJS 提供了三種方式用來打破孤立作用域“孤立”這一限制。

單向綁定(@ 或者 @attr)

這是 AngularJS 孤立作用域與外界父作用域進行數據通信中最簡單的一種,綁定的對象只能是父作用域中的字符串值,并且為單向只讀引用,無法對父作用域中的字符串值進行修改,此外,這個字符串還必須在父作用域的 HTML 節點中以 attr(屬性)的方式聲明。

使用這種綁定方式時,需要在 directive 的 scope 屬性中明確指定引用父作用域中的 HTML 字符串屬性,否則會拋異常。示例代碼如下:

清單 9. 單向綁定示例

<script>

 angular.module('isolateScope', [])

 .directive("isolateDirective", function () {

 return {

 replace : true,

 template: '<button>{{isolates}}</button>',

 scope : {

 isolates : '@',

 },

 link : function($scope, $element, $attr) {

 $scope.isolates = "DeveloperWorks";

 }

 };

 })

 .controller("ctrl", function ($scope) {

 $scope.btns = 'IBM';

 });

</script>

<body data-ng-app="isolateScope" >

<div data-ng-controller="ctrl">

 <button>{{btns}}</button>

 <div data-isolate-directive data-isolates="{{btns}}"></div>

 </div>

</body>

簡單分析下上面的代碼,通過在 directive 中聲明了 scope:{isolates:'@'} 使得 directive 擁有了父作用域中 data-isolates 這個 HTML 屬性所擁有的值,這個值在控制器 ctrl 中被賦值為'IBM'。所以,代碼的運行結果是頁面上有兩個名為 IBM 的按鈕。

我們還注意到 link 函數中對 isolates 進行了修改,但是最終不會在運行結果中體現。這是因為 isolates 始終綁定為父作用域中的 btns 字符串,如果父作用域中的 btns 不改變,那么在孤立作用域中無論怎么修改 isolates 都不會起作用。

引用綁定(&或者&attr)

通過這種形式的綁定,孤立作用域將有能力訪問到父作用域中的函數對象,從而能夠執行父作用域中的函數來獲取某些結果。這種方式的綁定跟單向綁定一樣,只能以只讀的方式訪問父作用函數,并且這個函數的定義必須寫在父作用域 HTML 中的 attr(屬性)節點上。

這種方式的綁定雖然無法修改父作用域的 attr 所設定的函數對象,但是卻可以通過執行函數來改變父作用域中某些屬性的值,來達到一些預期的效果。示例代碼如下:

清單 10. 引用綁定示例

<script>

 angular.module('isolateScope', [])

 .directive("isolateDirective", function () {

 return {

 replace : true,

 scope : {

 isolates : '&',

 },

 link : function($scope, $element, $attr) {

 var func = $scope.isolates();

 func();

 }

 };

 })

 .controller("ctrl", function ($scope) {

 $scope.func = function () {

 console.log("IBM DeveloperWorks");

 }

 });

</script>

<body data-ng-app="isolateScope" >

 <div data-ng-controller="ctrl"> 

 <div data-isolate-directive data-isolates="func"></div>

 </div> 

</body>

這個例子中,瀏覽器的控制臺將會輸出一段“IBM DeveloperWorks”文字。

上面的代碼中我們在父作用域中指定了一個函數對象$scope.func,在孤立作用域中通過對 HTML 屬性的綁定從而引用了 func。需要注意的是 link 函數中對 func 對象的使用方法,$scope.isolates 獲得的僅僅是函數對象,而不是調用這個對象,因此我們需要在調用完$scope.isolates 之后再調用這個函數,才能得到真正的執行結果。

雙向綁定(=或者=attr)

雙向綁定賦予 AngularJS 孤立作用域與外界最為自由的雙向數據通信功能。在雙向綁定模式下,孤立作用域能夠直接讀寫父作用域中的屬性和數據。和以上兩種孤立作用域定義數據綁定一樣,雙向綁定也必須在父作用域的 HTML 中設定屬性節點來綁定。

雙向綁定非常適用于一些子 directive 需要頻繁和父作用域進行數據交互,并且數據比較復雜的場景。不過,由于可以自由的讀寫父作用域中的屬性和對象,所以在一些多個 directive 共享父作用域數據的場景下需要小心使用,很容易引起數據上的混亂。

示例代碼如下:

清單 11. 雙向綁定示例

<script>

 angular.module('isolateScope', [])

 .directive("isolateDirective", function () {

 return {

 replace : true,

 template: '<button>{{isolates}}</button>',

 scope : {

 isolates : '=',

 },

 link : function($scope, $element, $attr) {

 $scope.isolates.ibm = "IBM";

 }

 };

 })

 .controller("ctrl", function ($scope) {

 $scope.btns = {

 ibm : 'ibm',

 dw : 'DeveloperWorks'

 }; 

 });

</script>

<body data-ng-app="isolateScope" >

 <div data-ng-controller="ctrl">

 <button>{{btns.dw}}</button>

 <button>{{btns.ibm}}</button>

 <div data-isolate-directive data-isolates="btns"></div>

 </div>

</body>

上面的代碼運行的結果是瀏覽器頁面上出現三個按鈕,其中第一個按鈕標題為“DeveloperWorks”,第二和第三個按鈕的標題為“IBM”。

初始時父作用域中的$scope.btns.ibm 為小寫的“ibm”,通過雙向綁定,孤立作用域中將父作用域的 ibm 改寫成為大寫的“IBM”并且直接生效,父作用域的值被更改。

總結

由于 AngularJS 框架的輕量性和其清晰的 MVC 特點使得其在推出之后就大受歡迎,實踐中也很容易上手。AngularJS 比較難以掌握和理解的就是其作用域和綁定機制,本文重點將作用域和綁定機制做了分析與討論,希望讀者能夠理解并熟練掌握這塊內容。

更多信息請查看網絡編程
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
久久人人97超碰人人澡爱香蕉| 欧美不卡一区| 国产精品一区视频网站| 欧美日韩综合另类| 欧美三日本三级三级在线播放| 国产精品第十页| 国产日韩欧美一二三区| 国内激情久久| 国产亚洲精品bt天堂精选| 国产色综合网| 国产精品v日韩精品| 亚洲高清激情| 亚洲日韩成人| 亚洲一区视频在线| 久久国产一区二区| 欧美日韩成人综合| 国产精品毛片a∨一区二区三区|国| 欧美另类在线播放| 欧美激情1区2区| 国产精品久久久久久久久搜平片| 国产精品一区二区a| 在线成人亚洲| 中文亚洲视频在线| 久久免费一区| 欧美日韩国产影片| 国产日韩欧美电影在线观看| 在线观看欧美日韩国产| 亚洲靠逼com| 一区在线免费观看| 亚洲国产高清在线| 91久久久亚洲精品| 亚洲图片在区色| 看片网站欧美日韩| 国产精品久久福利| 亚洲国产精品一区二区尤物区| 亚洲色图自拍| 免费成年人欧美视频| 国产精品进线69影院| 亚洲电影免费观看高清完整版在线观看 | 欧美一区激情| 男人插女人欧美| 欧美色道久久88综合亚洲精品| 国产女精品视频网站免费| 亚洲第一在线综合网站| 亚洲尤物精选| 欧美激情精品久久久久| 国模精品一区二区三区色天香| 日韩午夜av电影| 久久免费国产| 国产欧美日韩不卡| 99精品欧美一区二区三区| 久久久久综合一区二区三区| 国产精品多人| 日韩视频在线免费观看| 久久久水蜜桃| 国产欧美日韩精品在线| 一区二区电影免费在线观看| 欧美ed2k| 亚洲国产天堂网精品网站| 久久精品视频网| 国产精品视频不卡| 午夜精品短视频| 国产精品久久久久影院亚瑟| 亚洲一区三区在线观看| 国产精品不卡在线| 欧美一区二粉嫩精品国产一线天| 欧美日韩亚洲一区三区 | 欧美一区国产二区| 在线免费观看视频一区| 亚洲综合二区| 国产精品久久久久久久久久直播| 在线亚洲一区观看| 欧美日韩精品一区二区| 在线亚洲精品| 欧美午夜电影一区| 一本色道88久久加勒比精品| 欧美大片在线观看| 欧美国产精品va在线观看| 国语自产在线不卡| 久久久蜜桃一区二区人| 黄色成人在线免费| 久久综合九色综合久99| 黄色成人91| 麻豆成人在线播放| 亚洲高清三级视频| 欧美粗暴jizz性欧美20| 91久久午夜| 欧美日韩和欧美的一区二区| 99视频日韩| 国产精品久久77777| 亚洲女性喷水在线观看一区| 欧美日韩国产成人在线观看| 在线观看欧美成人| 久久亚洲国产成人| 欧美日韩精品免费观看视频| 国产一区二区黄色| 亚洲亚洲精品在线观看 | 国产精品久久久久久久久久免费 | 一区二区三区视频在线看| 美日韩精品免费| 91久久精品国产91久久性色tv| 美女国内精品自产拍在线播放| 亚洲激情中文1区| 国产精品一区二区久久精品 | 亚洲永久免费av| 蜜桃av综合| 欧美在线精品免播放器视频| 亚洲黄色在线视频| 夜夜夜精品看看| 日韩一级在线| 欧美风情在线观看| 午夜综合激情| 亚洲高清激情| 国产一区二区日韩精品| 国产精品国产三级国产专播精品人 | 久久美女艺术照精彩视频福利播放| 亚洲人成网站777色婷婷| 国产精品v欧美精品v日韩精品| 午夜激情综合网| 亚洲国产午夜| 激情视频一区| 欧美一级艳片视频免费观看| 美腿丝袜亚洲色图| 一区二区激情| 黄色成人在线网站| 欧美日韩一区在线视频| 久久精品人人做人人综合| 日韩视频在线播放| 国产一区久久久| 国产精品hd| 你懂的视频欧美| 中国女人久久久| 精品福利免费观看| 国产精品美女在线| 欧美阿v一级看视频| 午夜国产一区| 一本色道久久99精品综合 | 亚洲精品日韩久久| 欧美精品午夜视频| 久久久www| 亚洲欧美激情精品一区二区| 亚洲精品在线观| 欧美日韩三区| 欧美国产精品久久| 久久亚裔精品欧美| 欧美一区二区三区免费看 | 亚洲欧美精品| 亚洲精品国产系列| 今天的高清视频免费播放成人| 美乳少妇欧美精品| 久久xxxx精品视频| 亚洲一区黄色| 日韩一本二本av| 亚洲精品久久久久久下一站| 好吊色欧美一区二区三区四区| 国产精品视频自拍| 欧美日韩免费网站| 欧美久久久久久| 欧美激情精品久久久久久久变态| 久久午夜色播影院免费高清| 欧美在线观看日本一区| 久久久一区二区| 久久人人97超碰国产公开结果| 亚洲一区尤物| 欧美在线一二三| 午夜精品电影| 久久人人爽国产| 久久一区视频| 欧美精品乱码久久久久久按摩| 欧美国产视频在线| 欧美a级大片| 欧美私人啪啪vps| 欧美日韩一区不卡| 国产精品午夜视频| 国产日韩在线看| 亚洲国产三级网| 一区二区av| 欧美在线亚洲综合一区| 久久久久久**毛片大全| 亚洲国产精品成人综合| 日韩午夜黄色| 亚洲影院色无极综合| 性亚洲最疯狂xxxx高清| 国产精品久久久久一区| 国产精品99久久久久久有的能看| 国产精品成人在线观看| 国产精品制服诱惑| 亚洲欧洲一区二区在线播放| 9色国产精品| 欧美精品在线播放| 一区二区高清视频| 欧美成人黑人xx视频免费观看| 一色屋精品亚洲香蕉网站| 久久精品免费| 亚洲精品国产精品乱码不99按摩 | 亚洲欧美视频一区| 欧美性猛交xxxx乱大交蜜桃| 亚洲免费成人av| 国产精品久久久久久久久动漫| 日韩手机在线导航|