


AngularJS deep dive into scopes, inheritance structures, event systems, and lifecycle
Dec 08, 2016 am 09:58 AMThe examples in this article describe the scope, inheritance structure, event system and life cycle of AngularJS. Share it with everyone for your reference, the details are as follows:
In-depth discussion of Scope scope
Every $scope is an instance of the class Scope. Class Scope has methods that can control the scope life cycle, provides the ability to propagate events, and supports template rendering.
Scope hierarchy
Let’s take a look at this simple HelloCtrl example again:
var HelloCtrl = function($scope){ $scope.name = 'World'; }
HelloCtrl looks like an ordinary JavaScript constructor. In fact, except for the $scope parameter, Other than that, there's really nothing new about it. But where does this parameter come from?
This new scope is generated by the ng-controller directive using the Scope.$new() method. Wait, so we have to have at least one instance of scope in order to create a new scope! Yes, AngularJS actually has a $rootScope (this is the parent of all other scopes). This $rootScope instance is created when a new application starts. The
ng-controller directive is one of the directives that can create scopes. AngularJS will create a new instance of the Scope class whenever it encounters this create-scope directive in the DOM tree. These newly created scopes point to their own parent scope via the $parent property. There will be many directives in the DOM tree that can create scopes. As a result, many scopes are created.
The form of scope is similar to a parent-child, tree-like relationship, and the root is the $rootScope instance. Just like scope creation is driven by the DOM tree, the scope tree also mimics the structure of the DOM.
Now that you know that some directives create new child scopes, you might be wondering why all this complexity is needed. To understand this, let’s demonstrate an example where the ng-repeat loop directive is used.
The controller is as follows:
var WorldCtrl = function ($scope) { $scope.population = 7000; $scope.countries = [ {name: 'France', population: 63.1}, {name: 'United Kingdom', population: 61.8}, ]; };
The template is as follows:
<ul ng-controller="WorldCtrl"> <li ng-repeat="country in countries"> {{country.name}} has population of {{country.population}} </li> <hr> World's population: {{population}} millions </ul>
This ng-repeat directive can iterate a collection of countries and create a new DOM element for each item in the collection. The syntax of the ng-repeat directive is very easy to understand; each item requires a new variable country and hangs it on $scope for view rendering.
But there is a problem here, that is, each country needs to mount a new variable to a $scope, and we cannot simply overwrite the previously mounted value. AngularJS solves this problem by creating a new scope for each element in the collection. These newly created scopes are very similar to the matching DOM tree structure, which we can also visualize with the awesome Chrome extension Batarang mentioned earlier.
Each scope (bounded by a rectangle) maintains its own data model. There is absolutely no problem in adding variables with the same name to different scopes, and no naming conflicts will occur (different DOM elements will point to different scopes, and use the variables of the corresponding scope to render the template). In this way, each element has its own namespace. In the previous example, each
Scope’s hierarchy and inheritance
The attributes defined on the scope are visible to its sub-scopes. Just imagine, the sub-scope does not need to repeatedly define attributes with the same name! This is very useful in practice because we don't have to redefine properties over and over that would otherwise be available through the scope chain.
Looking at the previous example again, let’s say we want to display the given percentage of these countries to the total world population. To implement this function, we can define a worldsPercentage method on a scope and manage it by WorldCtrl, as follows:
$scope.worldsPercentage = function (countryPopulation) { return (countryPopulation / $scope.population)*100; }
Then every scope instance created by ng-repeat will call this The method is as follows:
<li ng-repeat="country in countries"> {{country.name}} has population of {{country.population}}, {{worldsPercentage(country.population)}} % of the World's population </li>
The inheritance rules of scope in AngularJS are the same as the inheritance rules of prototype in JavaScript (when you need to read an attribute, you will keep querying to the top of the inheritance tree until you find it. to this property).
The risk of inheritance through the scope chain
This kind of inheritance through the scope hierarchical relationship is very intuitive and easy to understand when reading data. But when writing data, it becomes a bit complicated.
Let’s take a look, if we define a variable in a scope, regardless of whether it is in a child scope. The JavaScript code is as follows:
var HelloCtrl = function ($scope) { };
The code of the view is as follows:
<body ng-app ng-init="name='World'"> <h1>Hello, {{name}}</h1> <div ng-controller="HelloCtrl"> Say hello to: <input type="text" ng-model="name"> <h2>Hello, {{name}}!</h2> </div> </body>
Run this code, you can find that although the name variable is only defined in the top-level scope, Visible throughout the app! This means that the variable is inherited from the scope chain. In other words, variables are defined on the parent scope and then accessed in the child scope.
現(xiàn)在,我們一起來看看,如果在 中寫點(diǎn)字會(huì)發(fā)生什么,運(yùn)行結(jié)果你可能會(huì)感到吃驚,因?yàn)?HelloCtrl 控制器所初始化的作用域創(chuàng)建了一個(gè)新的變量,而不是直接去修改$rootScope 實(shí)例中的值。不過當(dāng)我們認(rèn)識(shí)到作用域也只不過是在彼此間進(jìn)行了原型繼承,也就不會(huì)覺得那么吃驚了。所有可以用在 JavaScript 對(duì)象上的原型繼承的規(guī)則,都可以同等的用在 作用域 的原型鏈繼承上去。畢竟 Scopes 作用域就是 JavaScript 對(duì)象嘛。
在子級(jí)作用域中去改變父級(jí)作用域上面的屬性有幾種方法。第一種,我們就直接通過 $parent 屬性來引用父級(jí)作用域,但我們要看到,這是一個(gè)非常不可靠的解決方案。麻煩之處就在于,ng-model 指令所使用的表達(dá)式非常嚴(yán)重的依賴于整個(gè)DOM結(jié)構(gòu)。比如就在 標(biāo)簽上面的哪里插入另一個(gè) 可創(chuàng)建作用域 的指令,那$parent 就會(huì)指向一個(gè)完全不同的作用域了。
就經(jīng)驗(yàn)來講,盡量避免使用 $parent 屬性,因?yàn)樗鼜?qiáng)制的把 AngularJS 表達(dá)式和你的模板所創(chuàng)建的 DOM 結(jié)構(gòu)捆綁在了一起。這樣一來,HTML結(jié)構(gòu)的一個(gè)小小的改動(dòng),都可能會(huì)讓整個(gè)應(yīng)用崩潰。
另一個(gè)解決方案就是,不要直接把屬性綁定到 作用域上,而是綁到一個(gè)對(duì)象上面,如下所示:
<body ng-app ng-init="thing = {name : 'World'}"> <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>
這個(gè)方案會(huì)更可靠,因?yàn)樗]有假設(shè) DOM 樹的結(jié)構(gòu)是什么樣子。
避免直接把數(shù)據(jù)綁定到 作用域的屬性上。應(yīng)優(yōu)先選擇把數(shù)據(jù)雙向綁定到對(duì)象的屬性上(然后再把對(duì)象掛到 scope 上)。就經(jīng)驗(yàn)而言,在給 ng-model 指令的表達(dá)式中,你應(yīng)該有一個(gè)點(diǎn)(例如, ng-model="thing.name")。
作用域?qū)蛹?jí)和事件系統(tǒng)
層級(jí)關(guān)系中的作用域可以使用 event bus(一種事件系統(tǒng))。AngularJS可以在作用域?qū)蛹?jí)中傳播具名的裝備齊全的事件。事件可以從任何一個(gè)作用域中發(fā)出,然后向上($emit)和向下($broadcast)四處傳播。
AngularJS核心服務(wù)和指令使用這種事件巴士來發(fā)出一些應(yīng)用程序狀態(tài)變化的重要事件。比如,我們可以監(jiān)聽$locationChangeSuccess 事件(由 $rootScope 實(shí)例發(fā)出),然后在任何 location(瀏覽器中就是URL)變化的時(shí)候都會(huì)得到通知,如下所示:
$scope.$on('$locationChangeSuccess', function(event, newUrl, oldUrl){ //react on the location change here //for example, update breadcrumbs based on the newUrl });
? ?
每一個(gè)作用域?qū)ο蠖紩?huì)有這個(gè) $on 方法,可以用來注冊(cè)一個(gè)作用域事件的偵聽器。這個(gè)函數(shù)所扮演的偵聽器在被調(diào)用時(shí)會(huì)有一個(gè) event 對(duì)象作為第一個(gè)參數(shù)。后面的參數(shù)會(huì)根據(jù)事件類型的不同與事件本身的配備一一對(duì)應(yīng)。
類似于 DOM 事件,我們可以調(diào)用 event 對(duì)象的 preventDefault() 和 stopPropagation() 方法。stopPropagation() 方法將會(huì)阻止事件沿著作用域?qū)蛹?jí)繼續(xù)冒泡,并且只在事件向上層傳播的時(shí)候($emit)才有效。
盡管 AngularJS 的事件系統(tǒng)是模仿了 DOM 的,但兩個(gè)事件傳播系統(tǒng)是完全獨(dú)立的,沒有任何共同之處。
雖然在作用域?qū)蛹?jí)中傳播事件對(duì)一些問題來說是一種非常優(yōu)雅方案(特別是對(duì)全局的,異步的狀態(tài)變化來說),但還是要適度使用。通常情況下,可以依靠雙向數(shù)據(jù)綁定來得到一個(gè)比較干凈的方案。在整個(gè) AngularJS 框架中,一共只發(fā)出($emit)了三個(gè)事件($includeContentRequested,$includeContentLoaded,$viewContentLoaded)和七個(gè)廣播($broadcast)($locationChangeStart, $locationChangeSuccess, $routeUpdate, $routeChangeStart,$routeChangeSuccess, $routeChangeError, $destroy)。正如你所看到的,作用域事件使用的非常少,我們應(yīng)該在發(fā)送自定義的事件之前認(rèn)真的評(píng)估一下其他的可選方案(多數(shù)會(huì)是雙向數(shù)據(jù)綁定)。
千萬不要在 AngularJS 中模仿 DOM 的基于事件的編程方式。大多數(shù)情況下,你的應(yīng)用會(huì)有更好的架構(gòu)方式,你也可以在雙向數(shù)據(jù)綁定這條路上深入探索。
作用域的生命周期
作用域需要提供相互隔離的命名空間,避免變量的命名沖突。作用域們都很小,而且被以層級(jí)的方式組織起來,對(duì)內(nèi)存使用的管理來說很有幫助。當(dāng)其中一個(gè)作用域不再需要 ,它就可以被銷毀了。結(jié)果就是,這個(gè)作用域所暴露出來的模型和方法就符合的垃圾回收的標(biāo)準(zhǔn)。
新的作用域通常是被 可創(chuàng)建作用域 的指令所生成和銷毀的。不過也可以使用 $new() 和 $destroy() 方法來手動(dòng)的創(chuàng)建和銷毀作用域。
希望本文所述對(duì)大家AngularJS程序設(shè)計(jì)有所幫助。

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Javascript is a very unique language. It is unique in terms of the organization of the code, the programming paradigm of the code, and the object-oriented theory. The issue of whether Javascript is an object-oriented language that has been debated for a long time has obviously been There is an answer. However, even though Javascript has been dominant for twenty years, if you want to understand popular frameworks such as jQuery, Angularjs, and even React, just watch the "Black Horse Cloud Classroom JavaScript Advanced Framework Design Video Tutorial".

In today's information age, websites have become an important tool for people to obtain information and communicate. A responsive website can adapt to various devices and provide users with a high-quality experience, which has become a hot spot in modern website development. This article will introduce how to use PHP and AngularJS to build a responsive website to provide a high-quality user experience. Introduction to PHP PHP is an open source server-side programming language ideal for web development. PHP has many advantages, such as easy to learn, cross-platform, rich tool library, development efficiency

With the continuous development of the Internet, Web applications have become an important part of enterprise information construction and a necessary means of modernization work. In order to make web applications easy to develop, maintain and expand, developers need to choose a technical framework and programming language that suits their development needs. PHP and AngularJS are two very popular web development technologies. They are server-side and client-side solutions respectively. Their combined use can greatly improve the development efficiency and user experience of web applications. Advantages of PHPPHP

With the rapid development of Web technology, Single Page Web Application (SinglePage Application, SPA) has become an increasingly popular Web application model. Compared with traditional multi-page web applications, the biggest advantage of SPA is that the user experience is smoother, and the computing pressure on the server is also greatly reduced. In this article, we will introduce how to build a simple SPA using Flask and AngularJS. Flask is a lightweight Py

With the popularity and development of the Internet, front-end development has become more and more important. As front-end developers, we need to understand and master various development tools and technologies. Among them, PHP and AngularJS are two very useful and popular tools. In this article, we will explain how to use these two tools for front-end development. 1. Introduction to PHP PHP is a popular open source server-side scripting language. It is suitable for web development and can run on web servers and various operating systems. The advantages of PHP are simplicity, speed and convenience

The content of this article is about the basic introduction to AngularJS. It has certain reference value. Now I share it with you. Friends in need can refer to it.

With the popularity of web applications, the front-end framework AngularJS has become increasingly popular. AngularJS is a JavaScript framework developed by Google that helps you build web applications with dynamic web application capabilities. On the other hand, for backend programming, PHP is a very popular programming language. If you are using PHP for server-side programming, then using PHP with AngularJS will bring more dynamic effects to your website.

With the popularity of the Internet, more and more people are using the network to transfer and share files. However, due to various reasons, using traditional methods such as FTP for file management cannot meet the needs of modern users. Therefore, establishing an easy-to-use, efficient, and secure online file management platform has become a trend. The online file management platform introduced in this article is based on PHP and AngularJS. It can easily perform file upload, download, edit, delete and other operations, and provides a series of powerful functions, such as file sharing, search,
