首頁 php教程 PHP开发 AngularJS深入探討scope,繼承結構,事件系統和生命週期

AngularJS深入探討scope,繼承結構,事件系統和生命週期

Dec 08, 2016 am 09:58 AM
angularjs

本文實例講述了AngularJS的scope,繼承結構,事件系統和生命週期。分享給大家供大家參考,具體如下:

深入探討 Scope 作用域

每一個 $scope 都是類 Scope 的一個實例。類別 Scope 擁有可以控制 scope 生命週期的方法,提供事件傳播的能力,並支援模板渲染。

作用域的層次結構

讓我們再來看看這個簡單的HelloCtrl 的例子:

var HelloCtrl = function($scope){
  $scope.name = 'World';
}
登入後複製

   

HelloCtrl 看起來跟普通的JavaScript 構造函數沒什麼,

HelloCtrl 看起來跟普通的JavaScript 構造函數沒什麼,實際上,除了$scope 這個參數之參數外,確實沒什麼新奇之處。不過,這個參數究竟是從哪裡來的呢?

這個新的作用域是由 ng-controller指令使用 Scope.$new() 方法產生的。等一下,這麼說來我們必須至少擁有一個 scope 的實例才能創建新的 scope!沒錯,AngularJS其實有一個 $rootScope(這個是所有其他作用域的父級)。這個 $rootScope 實例是在一個新的應用程式啟動的時候創建的。

ng-controller指令就是 可以創建作用域 指令的其中一個。 AngularJS 會在任何它在DOM樹中碰到這種 可以創建作用域 指令的時候創建一個新的 Scope類別的實例。這些新建立的作用域透過 $parent 屬性指向它本身的父作用域。 DOM樹中會有很多 可以創建作用域 的指令,結果就是,很多作用域都被創建了。

作用域的形式類似父子、樹狀的關係,而最根部的就是 $rootScope 實例。就像作用域是被DOM樹驅動創造的一樣,作用域樹也是在模仿 DOM 的結構。

現在你已經知道了,一些指令會創建新的子級的作用域,你可能會想,為什麼會需要這些複雜的東西。要理解這一點,我們來示範一個例子,其中使用了 ng-repeat 循環指令。

控制器如下:

var WorldCtrl = function ($scope) {
  $scope.population = 7000;
  $scope.countries = [
    {name: 'France', population: 63.1},
    {name: 'United Kingdom', population: 61.8},
  ];
};
登入後複製

   

模版如下:

<ul ng-controller="WorldCtrl">
  <li ng-repeat="country in countries">
    {{country.name}} has population of {{country.population}}
  </li>
  <hr>
  World&#39;s population: {{population}} millions
</ul>
登入後複製

   

這個指令

   

這個指令

   

這個指令

   

這個指令 的每一項都可以創建一個新的元素。 ng-repeat 指令的語法非常容易理解;其中每一項都需要一個新的變數 country,並把它掛到 $scope 上面,以便視圖渲染使用。

但這裡有一個問題,就是,每一個 country 都需要將一個新的變數掛載到一個 $scope 上去,而我們也不能就簡單的覆蓋掉前面被掛在上去的值。 AngularJS 透過為集合中的每一個元素創建一個新的作用域來解決這個問題。新創建的這些作用域跟相匹配的DOM樹結構非常相像,我們也能通過之前提到的那個牛逼的 Chrome 擴展 Batarang 來可視化的看到這一點。

每一個作用域(以矩形標註邊界)維護屬於她自己的一段資料模型。為不同的作用域增加同名的變數是完全沒有問題的,不會發生命名衝突(不同的DOM元素會指向不同的作用域,並使用相對應的作用域的變數來渲染模板)。這樣一來,每個元素又有自己的命名空間,在前面的例子中,每一個

  • 元素都有自己的作用域,而 country 變數就定義在各自的作用域上面。

    Scope的層次結構和繼承

    定義在作用於上的屬性對他的子級作用於來說是可見的,試想一下,子級作用域並不需要重複定義同名的屬性!這在實務上是非常有用的,因為我們不必一遍又一遍的重複定義本來可以透過作用域鏈得到的那些屬性。

    再來看看前面的例子,假設我們想要顯示給出的這些國家與世界總人口的百分比。要實現這個功能,我們可以在一個作用域上定義一個worldsPercentage 的方法,並由WorldCtrl 來管理,如下所以:

    $scope.worldsPercentage = function (countryPopulation) {
      return (countryPopulation / $scope.population)*100;
    }
    登入後複製

       

    然後被ng-repeat 創建的每一個作用域實例都來調用這個方法,如下:

    <li ng-repeat="country in countries">
      {{country.name}} has population of {{country.population}},
      {{worldsPercentage(country.population)}} % of the World&#39;s
      population
    </li>
    登入後複製

       

    AngularJS中作用域的繼承規則跟JavaScript 中原型的繼承規則是相同的(在需要讀取一個屬性的時候,會一直向繼承樹的上方查詢,直到找到了這個屬性為止)。

    貫穿作用域鏈的繼承的風險

    🎜這種透過作用域層次關係的繼承,在讀數據的時候顯得非常的直觀、易於理解。但是寫數據的時候,就變的有點複雜了。 🎜🎜讓我們來看看,如果我們在一個作用域上定義了一個變量,先不管是否在子級作用域上。 JavaScript程式碼如下:🎜
    var HelloCtrl = function ($scope) {
    };
    登入後複製
    🎜   🎜🎜🎜🎜視圖的程式碼如下:🎜
    <body ng-app ng-init="name=&#39;World&#39;">
      <h1>Hello, {{name}}</h1>
      <div ng-controller="HelloCtrl">
        Say hello to: <input type="text" ng-model="name">
        <h2>Hello, {{name}}!</h2>
      </div>
    </body>
    登入後複製
    🎜   🎜🎜🎜🎜運行一下這段程式碼,就可以發現,這個name 變數儘管是頂級定義在這個做了在整個應用中都是可見的!這說明變數是從作用域鏈繼承下來的。換句話說,變數是在父級作用域上定義的,然後在子級作用域中存取的。 🎜

    现在,我们一起来看看,如果在 中写点字会发生什么,运行结果你可能会感到吃惊,因为 HelloCtrl 控制器所初始化的作用域创建了一个新的变量,而不是直接去修改$rootScope 实例中的值。不过当我们认识到作用域也只不过是在彼此间进行了原型继承,也就不会觉得那么吃惊了。所有可以用在 JavaScript 对象上的原型继承的规则,都可以同等的用在 作用域 的原型链继承上去。毕竟 Scopes 作用域就是 JavaScript 对象嘛。

    在子级作用域中去改变父级作用域上面的属性有几种方法。第一种,我们就直接通过 $parent 属性来引用父级作用域,但我们要看到,这是一个非常不可靠的解决方案。麻烦之处就在于,ng-model 指令所使用的表达式非常严重的依赖于整个DOM结构。比如就在 标签上面的哪里插入另一个 可创建作用域 的指令,那$parent 就会指向一个完全不同的作用域了。

    就经验来讲,尽量避免使用 $parent 属性,因为它强制的把 AngularJS 表达式和你的模板所创建的 DOM 结构捆绑在了一起。这样一来,HTML结构的一个小小的改动,都可能会让整个应用崩溃。

    另一个解决方案就是,不要直接把属性绑定到 作用域上,而是绑到一个对象上面,如下所示:

    <body ng-app ng-init="thing = {name : &#39;World&#39;}">
      <h1>Hello, {{thing.name}}</h1>
      <div ng-controller="HelloCtrl">
        Say hello to: <input type="text" ng-model="thing.name">
        <h2>Hello, {{thing.name}}!</h2>
      </div>
    </body>
    登入後複製

    这个方案会更可靠,因为他并没有假设 DOM 树的结构是什么样子。

    避免直接把数据绑定到 作用域的属性上。应优先选择把数据双向绑定到对象的属性上(然后再把对象挂到 scope 上)。就经验而言,在给 ng-model 指令的表达式中,你应该有一个点(例如, ng-model="thing.name")。

    作用域层级和事件系统

    层级关系中的作用域可以使用 event bus(一种事件系统)。AngularJS可以在作用域层级中传播具名的装备齐全的事件。事件可以从任何一个作用域中发出,然后向上($emit)和向下($broadcast)四处传播。

    AngularJS核心服务和指令使用这种事件巴士来发出一些应用程序状态变化的重要事件。比如,我们可以监听$locationChangeSuccess 事件(由 $rootScope 实例发出),然后在任何 location(浏览器中就是URL)变化的时候都会得到通知,如下所示:

    $scope.$on(&#39;$locationChangeSuccess&#39;, function(event, newUrl, oldUrl){
      //react on the location change here
      //for example, update breadcrumbs based on the newUrl
    });
    登入後複製

       

    每一个作用域对象都会有这个 $on 方法,可以用来注册一个作用域事件的侦听器。这个函数所扮演的侦听器在被调用时会有一个 event 对象作为第一个参数。后面的参数会根据事件类型的不同与事件本身的配备一一对应。

    类似于 DOM 事件,我们可以调用 event 对象的 preventDefault() 和 stopPropagation() 方法。stopPropagation() 方法将会阻止事件沿着作用域层级继续冒泡,并且只在事件向上层传播的时候($emit)才有效。

    尽管 AngularJS 的事件系统是模仿了 DOM 的,但两个事件传播系统是完全独立的,没有任何共同之处。

    虽然在作用域层级中传播事件对一些问题来说是一种非常优雅方案(特别是对全局的,异步的状态变化来说),但还是要适度使用。通常情况下,可以依靠双向数据绑定来得到一个比较干净的方案。在整个 AngularJS 框架中,一共只发出($emit)了三个事件($includeContentRequested,$includeContentLoaded,$viewContentLoaded)和七个广播($broadcast)($locationChangeStart, $locationChangeSuccess, $routeUpdate, $routeChangeStart,$routeChangeSuccess, $routeChangeError, $destroy)。正如你所看到的,作用域事件使用的非常少,我们应该在发送自定义的事件之前认真的评估一下其他的可选方案(多数会是双向数据绑定)。

    千万不要在 AngularJS 中模仿 DOM 的基于事件的编程方式。大多数情况下,你的应用会有更好的架构方式,你也可以在双向数据绑定这条路上深入探索。

    作用域的生命周期

    作用域需要提供相互隔离的命名空间,避免变量的命名冲突。作用域们都很小,而且被以层级的方式组织起来,对内存使用的管理来说很有帮助。当其中一个作用域不再需要 ,它就可以被销毁了。结果就是,这个作用域所暴露出来的模型和方法就符合的垃圾回收的标准。

    新的作用域通常是被 可创建作用域 的指令所生成和销毁的。不过也可以使用 $new() 和 $destroy() 方法来手动的创建和销毁作用域。

    希望本文所述对大家AngularJS程序设计有所帮助。


  • 本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    威爾R.E.P.O.有交叉遊戲嗎?
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    2022年最新5款的angularjs教學從入門到精通 2022年最新5款的angularjs教學從入門到精通 Jun 15, 2017 pm 05:50 PM

    Javascript 是一個非常有個性的語言. 無論是從程式碼的組織, 還是程式碼的程式設計範式, 或物件導向理論都獨具一格. 而很早就在爭論的Javascript 是不是物件導向語言這個問題, 顯然已有答案. 但是, 即使Javascript 叱吒風雲二十年, 如果想要看懂jQuery, Angularjs, 甚至是React 等流行框架, 觀看《黑馬雲課堂JavaScript 高級框架設計視頻教程》就對了。

    使用PHP和AngularJS建立響應式網站,提供優質的使用者體驗 使用PHP和AngularJS建立響應式網站,提供優質的使用者體驗 Jun 27, 2023 pm 07:37 PM

    在現今資訊時代,網站已成為人們獲取資訊和交流的重要工具。一個響應式的網站能夠適應各種設備,為使用者提供優質的體驗,成為了現代網站開發的熱點。本篇文章將介紹如何使用PHP和AngularJS建立響應式網站,進而提供優質的使用者體驗。 PHP介紹PHP是一種開源的伺服器端程式語言,非常適合Web開發。 PHP具有許多優點,如易於學習、跨平台、豐富的工具庫、開發效

    使用PHP和AngularJS建立Web應用 使用PHP和AngularJS建立Web應用 May 27, 2023 pm 08:10 PM

    隨著網路的不斷發展,Web應用已成為企業資訊化建設的重要組成部分,也是現代化工作的必要手段。為了讓Web應用能夠方便開發、維護和擴展,開發人員需要選擇適合自己開發需求的技術框架和程式語言。 PHP和AngularJS是兩種非常流行的Web開發技術,它們分別是伺服器端和客戶端的解決方案,透過結合使用可以大大提高Web應用的開發效率和使用體驗。 PHP的優勢PHP

    使用Flask和AngularJS建立單頁Web應用程式 使用Flask和AngularJS建立單頁Web應用程式 Jun 17, 2023 am 08:49 AM

    隨著Web技術的快速發展,單頁Web應用程式(SinglePageApplication,SPA)已成為越來越流行的Web應用程式模型。相較於傳統的多頁Web應用程序,SPA的最大優勢在於使用者感受更加流暢,同時伺服器端的運算壓力也大幅減少。在本文中,我們將介紹如何使用Flask和AngularJS來建構一個簡單的SPA。 Flask是一款輕量級的Py

    使用PHP和AngularJS開發一個線上文件管理平台,方便文件管理 使用PHP和AngularJS開發一個線上文件管理平台,方便文件管理 Jun 27, 2023 pm 01:34 PM

    隨著網路的普及,越來越多的人使用網路進行檔案傳輸和分享。然而,由於各種原因,使用傳統的FTP等方式進行檔案管理無法滿足現代使用者的需求。因此,建立一個易用、高效、安全的線上文件管理平台已成為了一種趨勢。本文介紹的線上文件管理平台,基於PHP和AngularJS,能夠方便地進行文件上傳、下載、編輯、刪除等操作,並且提供了一系列強大的功能,例如文件共享、搜尋、

    AngularJS基礎入門介紹 AngularJS基礎入門介紹 Apr 21, 2018 am 10:37 AM

    這篇文章介紹的內容是關於AngularJS基礎入門介紹,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下。

    如何在PHP編程中使用AngularJS? 如何在PHP編程中使用AngularJS? Jun 12, 2023 am 09:40 AM

    隨著Web應用程式的普及,前端框架AngularJS變得越來越受歡迎。 AngularJS是一個由Google開發的JavaScript框架,它可以幫助你建立具有動態Web應用程式功能的網頁應用程式。另一方面,對於後端編程,PHP是非常受歡迎的程式語言。如果您正在使用PHP進行伺服器端編程,那麼結合AngularJS使用PHP將可以為您的網站帶來更多的動態效

    如何使用PHP和AngularJS進行前端開發 如何使用PHP和AngularJS進行前端開發 May 11, 2023 pm 05:18 PM

    隨著網路的普及和發展,前端開發已變得越來越重要。身為前端開發人員,我們需要了解並掌握各種開發工具和技術。其中,PHP和AngularJS是兩種非常有用且受歡迎的工具。在本文中,我們將介紹如何使用這兩種工具進行前端開發。一、PHP介紹PHP是一種流行的開源伺服器端腳本語言,它適用於Web開發,可以在Web伺服器和各種作業系統上運作。 PHP的優點是簡單、快速、便

    See all articles