ANGULARJS-dependent injection simulation to realize _ANGULARJS

Source: Internet
Author: User
Tags function definition

I. Overview

Angularjs has a classic is to rely on injection, for what is dependency injection, familiar with spring students should be very understanding, but, for the front-end, or relatively novel.

Dependency Injection , in short, is to unlock the hard code to achieve the purpose of the uncoupling.

Below, let's look at the common implementations in ANGULARJS.

Method One: An inferred injection declaration, assuming that the parameter name is the name of the dependency. Therefore, it calls the ToString () method of the function object internally, analyzes and extracts the list of function arguments, and then injects the parameters into the object instance through $injector.

As follows:

Method One: An inferred injection declaration, assuming that the parameter name is the name of the dependency.
//Therefore, it calls the ToString () method of the function object internally, analyzes and extracts the list of function arguments,
//and injects these parameters into the object instance
injector.invoke (function) by $injector ( $http, $timeout) {
 //todo
});

Method Two: Inline declaration allows us to pass directly into an array of arguments when the function is defined, including strings and functions, where the string represents a dependency, and the function represents the object of the target function.
As follows:

Method Two: Inline declaration allows us to pass directly to an array of arguments in the function definition,
//array containing strings and functions, where the string represents a dependency, and the function represents the target function object.
module.controller (' name ', [' $http ', ' $timeout ', function ($http, $timeout) {
 //todo
}]); 

Read the above code, there is a doubt in mind, how these are achieved?

Haha, next, let's simulate these dependency injection methods to get to know them.

second, build the basic skeleton

The acquisition process of dependency injection is to obtain the corresponding method through field mapping.

Therefore, to achieve a basic dependency injection, we need a storage space (dependencies), store the required key value (Key/value), a registration Method (register) for new key value pairs into storage space And another is the core implementation method (resolve), through the relevant parameters, to the storage space to obtain the corresponding mapping results.

So, the basic skeleton is as follows:

var injector = {
 dependencies: {},
 register:function (key, value) {
 This.dependencies[key] = value;
 return this;
 },
 resolve:function () {
    
 }
};

third, improve the core method resolve

From the basic skeleton we have built, we can find that the focus is actually resolve method, which is used to realize our specific form of dependency injection requirements.

First, we implement dependency injection in the form of an inferred injection declaration.

As follows:

Injector.resolve (function (monkey, Dorie) {
 monkey ();
 Dorie ();
}); 

To achieve this effect, we can use the ToString () method of the function to convert the function to a string, thus obtaining the parameter name, the key value, through the regular expression. Then through the key value, in the storage space dependencies find value, no corresponding value, then the error.

Implemented as follows:

var injector = {
 dependencies: {},
 register:function (key, value) {
 This.dependencies[key] = value;
 return this;
 },
 resolve:function () {
 var func, deps, args = [], scope = NULL;
 func = arguments[0];
 Gets the function's parameter name
 deps = func.tostring (). Match (/^function\s*[^\ (]*\ (\s*) ^\)/m) []* (/1].replace, '). Split (', ') ;
 Scope = Arguments[1] | | {};
 for (var i = 0, len = deps.length i < len, d = deps[i]; i++) {
  if (This.dependencies[d]) {
  Args.push (this.depend Encies[d]);
  } else{
  throw new Error (' can\ ' t find ' + D);
  }
 Func.apply (scope, args);   
 }
;

Test the code as follows:

<! DOCTYPE html>  

Inference injection declaration, there is a disadvantage, that is, can not use compression tool compression, because we are dependent on the parameters of the function, when we compress, will be the parameter name change, parameter names changed, that certainly flutter street slightly.

So below, let's look at the inline injection declaration, which can compensate for this shortcoming.

Implement inline declaration, as follows:

 Injector.resolve ([' Monkey ', ' Dorie ', function (m, D) {
 m ();
 D ();
}]; 

Using typeof to determine the type of arguments[0] can identify and obtain dependent parameters and functions.

Implemented as follows:

var injector = {
 dependencies: {},
 register:function (key, value) {
 This.dependencies[key] = value;
 return this;
 },
 resolve:function () {
 var firstparams, func, Deps = [], scope = null, args = [];
 Firstparams = arguments[0];
 Scope = Arguments[1] | | {};
 Get dependency parameter for
 (var i = 0, len = firstparams.length i < len; i++) {
  var val = firstparams[i],
  type = typeof Val;
  if (type = = ' string ') {
  deps.push (val);
  } else if (type = = = ' function ') {
  func = val;
  }
 }
 The correlation value is found for
 (i = 0, len = deps.length i < len, d = deps[i], i++) {
  if (this.dependencies[d)) {args by relying on parameters
  . Push (This.dependencies[d]);
  } else{
  throw new Error (' can\ ' t find ' + D);
  }
 Func.apply (Scope | | {}, args);   
 }
;

Test the code as follows:

<! DOCTYPE html>  

Because inline declarations are used as dependency parameters in the form of strings, so, compression is not afraid.
  Finally, we integrate the two methods that are implemented above, and we can do whatever we want.
 , let's merge it, as follows:  

 var injector = {dependencies: {}, Register:function (key, value) {This.dependencies[ke
 Y] = value;
 return this;
 }, Resolve:function () {var firstparams, func, Deps = [], scope = null, args = [];
 Firstparams = Arguments[0]; Scope = Arguments[1] | |
 {};
  Determine which form of injection if (typeof firstparams = = ' function ') {func = Firstparams;
 Deps = Func.tostring (). Match (/^function\s*[^\ (]*\ (\s*) ^\)/m) []* (/1].replace, '). Split (', ');
  }else{for (var i = 0, len = firstparams.length i < len; i++) {var val = firstparams[i], type = typeof Val;
  if (type = = = ' String ') {Deps.push (val);
  }else if (type = = = ' function ') {func = Val; The association value is found for (i = 0, len = deps.length i < len, d = deps[i], i++) {if (this.dependencies[d)) {args by dependency parameters)
  . push (This.dependencies[d]);
  }else{throw new Error (' can\ ' t find ' + D); }} func.apply (Scope | |   
 {}, args);

}
}; 

Iv. The-requirejs of the trailer and the injection of dependency

Dependency injection is not in the ANGULARJS, if you have used Requirejs, then this form is not unfamiliar:

 Require ([' monkey ', ' dorie '], function (M, D) {
 //todo 
}); 

Through, above our step-by-step simulation angularjs Dependency Injection implementation, presumably, see this, you will be enlightened, the same.

The simulation implementation is as follows:

var injector = {
 dependencies: {},
 register:function (key, value) {
 This.dependencies[key] = value;
 return this;
 },
 resolve:function (Deps, func, scope) {
 var args = [];
 for (var i = 0, len = deps.length i < len, d = deps[i]; i++) {
  if (This.dependencies[d]) {
  Args.push (this.depend Encies[d]);
  } else{
  throw new Error (' can\ ' t resolve ' + D);
  }
 Func.apply (Scope | | {}, args);
 }
;

The test code is as follows:

<! DOCTYPE html>
  
 

V. Reference

1, ANGULARJS Application Development Thinking of 3: Dependency Injection
2. Dependency Injection in JavaScript

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.