Angularjs delve into scope, inheritance architecture, event systems, and Lifecycle _angularjs

Source: Internet
Author: User
Tags emit garbage collection memory usage

This example describes the scope, inheritance structure, event System, and lifecycle of Angularjs. Share to everyone for your reference, specific as follows:

Explore scope scopes in depth

Each $scope is an instance of class scope. Class Scope has methods that can control the Scope lifecycle, provides the ability to propagate events, and supports template rendering.

Scope hierarchy

Let's take a look at this simple Helloctrl example:

var Helloctrl = function ($scope) {
  $scope. Name = ' World ';


Helloctrl looks like a normal JavaScript constructor, and in fact there is nothing new about it except $scope this argument. But where does this parameter come from?

This new scope is generated by the Ng-controller directive using the Scope. $new () method. Wait a minute, so we have to have at least one instance of scope to create a new scope! Yes, Angularjs actually has a $rootScope (this is the parent of all other scopes). This $rootScope instance was created when a new application was started.

The ng-controller instruction is one of the scope directives that can be created. Angularjs will create an instance of a new scope class whenever it encounters such a scope directive in the DOM tree. These newly created scopes point to its own parent scope by $parent attribute. There are many directives in the DOM tree that can create scopes, and as a result, many scopes are created.

The form of a scope is similar to a parent-child, tree-like relationship, and the root is $rootScope instance. As the scope is driven by the DOM tree, the scope tree is mimicking the structure of the DOM.

Now that you know, some directives will create new child scopes, and you may wonder why you need these complex things. To understand this, let's demonstrate an example that uses the ng-repeat loop instruction.

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>
   
 

This ng-repeat instruction can iterate over a countries collection and create a new DOM element for each item in the collection. The syntax of the ng-repeat instruction is very easy to understand, each of which requires a new variable country and hangs it on the $scope so that the view renders it available.

But here's the problem: every country needs to mount a new variable to a $scope, and we can't simply cover the values that were hanging up in front. Angularjs solves this problem by creating a new scope for each element in the collection. The newly created scopes are very much like the matching DOM tree structure, and we can see this visually by using the awesome Chrome extension Batarang mentioned earlier.

Each scope (with a rectangular callout boundary) maintains a piece of her own data model. Adding a variable with the same name to a different scope is perfectly fine and does not cause a naming conflict (different DOM elements point to different scopes and use the corresponding scope variables to render the template). As a result, each element has its own namespace, in the previous example, each <li> element has its own scope, and the country variable is defined on its own scope.

Hierarchy and inheritance of scope

The attribute defined for use on is visible to his child, imagine that the child scope does not need to repeatedly define an attribute of the same name! This is useful in practice because we do not have to repeat the definition of those attributes that could have been obtained through the scope chain.

Let's take a look at the previous example, assuming we want to show the percentage of these countries and the total population of the world. To implement this function, we can define a Worldspercentage method on a scope and be managed by Worldctrl, as follows:

$scope. worldspercentage = function (countrypopulation) {return 
  (countrypopulation/$scope. Population) *100;
}

The method is then invoked by each of the scope instances created by Ng-repeat, 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 for scopes in Angularjs are the same as those of JavaScript-style (when you need to read a property, you'll always query the inheritance tree until you find this property).

Risk of inheritance across the scope chain

This inheritance through the scope-level relationship is very intuitive and easy to understand when reading data. But when it comes to writing data, it gets a little bit more complicated.

Let's see if we define a variable on a scope, regardless of whether it's on the child scope or not. The JavaScript code is as follows:

var Helloctrl = function ($scope) {
};

The code for the view is as follows:

<body ng-app ng-init= "Name= ' World" "> 
   
 

If you run this code, you can see that the name variable, although it is only defined at the top of the scope, is visible throughout the application! This indicates that the variable is inherited from the scope chain. In other words, the variables are defined on the parent scope and then accessed in the child scope.

Now, let's take a look at what happens when you write a word in <input>, and you might be surprised to run the results because the Helloctrl controller initializes a new variable instead of directly modifying the value in the $rootscope instance. But we don't feel so surprised when we realize that the scope is just a prototype inheritance between each other. All the rules that can be inherited from a prototype on a JavaScript object can be inherited equally by the scope of the prototype chain. After all, scopes scopes are JavaScript objects.

There are several ways to change the properties above the parent scope in the child scope. First, we refer directly to the parent scope by $parent attribute, but we want to see that this is a very unreliable solution. The trouble is that the expression used by the Ng-model directive is heavily dependent on the entire DOM structure. For example, just where on the <input> tab insert another directive that can create scopes, the $parent will point to a completely different scope.

As far as experience is concerned, avoid using $parent attributes, because it forces the ANGULARJS expression to be bundled with the DOM structure created by your template. As a result, a small change in the HTML structure could crash the entire application.

Another solution is not to bind the attribute directly to the scope, but to bind it to an object, as follows:

<body Ng-app ng-init= "thing = {name: ' World '}" > 
   
 

This scheme will be more reliable because he does not assume that the structure of the DOM tree is what it looks like.

Avoid binding data directly to the properties of the scope. Priority should be given to binding data in both directions to the object's properties (and then to the object on scope). In terms of experience, you should have a point (for example, ng-model= "Thing.name") in an expression that gives Ng-model instructions.

Scope Hierarchies and event systems

The scope in a hierarchical relationship can use event bus (an event system). Angularjs can propagate named, fully equipped events at the scoping level. Events can be emitted from any scope and then spread up ($emit) and Down ($broadcast).

Angularjs Core Services and directives use this event bus to emit important events for application state changes. For example, we can listen for $locationchangesuccess events (emitted by $rootScope instances) and then be notified when any location (URL in the browser) changes, as follows:

$scope. $on (' $locationChangeSuccess ', function (event, Newurl, Oldurl) { 
  //react on the location
  For example, update breadcrumbs based on the Newurl
});

Each scope object will have this $on method that can be used to register a listener for a scope event. The listener acting on this function will have an event object as the first argument when invoked. The following parameters correspond to one by one of the events themselves, depending on the type of event.

Similar to DOM events, we can invoke the Preventdefault () and Stoppropagation () methods of the event object. The Stoppropagation () method will prevent the event from bubbling along the scope level and is valid only when the event propagates to the upper layer ($emit).

Although the Angularjs event system is modeled on DOM, two event-propagation systems are completely independent and have nothing in common.

Although propagating events at the scope level is a very elegant solution for some problems (especially for global, asynchronous state changes), it should be used moderately. Typically, you can rely on two-way data binding to get a cleaner solution. In the entire ANGULARJS framework, only three events ($emit) were issued ( $includeContentRequested, $includeContentLoaded, $viewContentLoaded) and seven broadcasts ($broadcast) ($locationChangeStart, $locationChangeSuccess, $routeUpdate, $routeChangeStart, $ Routechangesuccess, $routeChangeError, $destroy). As you can see, scope events use very little, and we should carefully evaluate other alternatives (most of which are two-way data binding) before sending custom events.

Never emulate DOM's event-based programming in Angularjs. In most cases, your application will have a better architectural approach, and you can explore it in a two-way data-binding way.

The life cycle of a scope

Scopes need to provide mutually isolated namespaces to avoid naming conflicts for variables. Scopes are small and organized in a hierarchical manner, which is useful for managing memory usage. When one of the scopes is no longer needed, it can be destroyed. The result is that the models and methods exposed by this scope meet the criteria for garbage collection.

The new scope is usually generated and destroyed by an instruction that can create scopes. However, you can also use the $new () and $destroy () methods to manually create and destroy scopes.

I hope this article will help you to Angularjs program design.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.