AngularJS dependency injection instance analysis (using module and injector), angularjsinjector
This article analyzes the dependency injection of AngularJS. We will share this with you for your reference. The details are as follows:
The benefits of dependency injection (DI) are no longer described in detail. Anyone who has used the spring framework knows the benefits. AngularJS, as a front-end js framework, also provides DI support, which is a feature not available in JavaScript/jQuery. In angularjs, there are DI-related angular. module (), angular. injector (), $ injector, and $ provide. A di container must have three elements: Service Registration, dependency declaration, and object acquisition. For example, in spring, Service registration is implemented through the <bean> tag or annotation @ Repository, @ Service, @ Controller, and @ Component in the xml configuration file. The collection of objects can be ApplicationContext. getBean () implementation; Dependency declaration, which can be configured in the xml file or declared in Java code using annotations such as @ Resource. In angular, module and $ provide are equivalent to service registration; injector is used to obtain objects (angular automatically completes dependency injection); there are three ways to declare dependency in angular. The following describes the DI of angular from these three aspects.
1. angular. module () creates, obtains, and registers modules in angular.
The angular. module () is a global place for creating, registering and retrieving Angular modules. when passed two or more arguments, a new module is created. if passed only one argument, an existing module (the name passed as the first argument to module) is retrieved.
// When more than one parameter is passed, it indicates creating a module. An empty array indicates that the module does not depend on other modules. var createModule = angular. module ("myModule", []); // only one parameter (module name) indicates the module to be retrieved. // If the module does not exist, the angular framework throws an exception var getModule = angular. module ("myModule"); // true, all are the same module alert (createModule = getModule );
This function can be used to create a new module or obtain an existing module. It can be distinguished by the number of parameters.
Angular. module (name, [requires], [configFn]);
Name: string type, which indicates the module name;
Requires: A String Array that represents the list of other modules that the module depends on. If it does not depend on other modules, use an empty array;
ConfigFn: used to configure the module.
Now we know how to create and retrieve modules. What is the module? There is only one sentence on the official Developer Guide: You can think of a module as a Container for the different parts of your app-controllers, services, filters, directives, etc. I still don't quite understand it yet, that is, the module is a collection of functions, such as controllers, services, filters, commands, and other sub-elements. I can't explain it now.
2. Relationship between $ provide and modules
The $ provide service has a number of methods for registering components with the $ injector. Attributes of these functions are also exposed on angular. Module.
Previously mentioned: module and provide are used to register services in injector. View the official API. You can see that $ provide provides provide (), constant (), value (), factory (), and service () to create services of different natures. angular. module also provides these five service registration methods. In fact, the two functions are exactly the same, that is, they are used to register services to injector with DI containers.
In the official API, auto has $ provide and $ injector, and Implicit module which gets automatically added to each $ injector. Literally, each injector has these two Implicit services. However, in version 1.2.25, it seems that there is no way to obtain $ provide in injector. I don't know why? Generally, you do not need to use this service. simply use the API provided in the module.
var injector = angular.injector();alert(injector.has("$provide"));//falsealert(injector.has("$injector"));//true
3. angular. injector ()
Angular. injector (); can also be used to obtain the injector, but it is not bound to the module. This method is meaningless, so you have created an empty DI container, which does not serve others. The correct method is to specify the module to be loaded when creating the injector.
// Create the myModule module and register the service var myModule = angular. module ('mymodule', []); myModule. service ('myservice', function () {this. my = 0 ;}); // create the herModule and register the var herModule = angular service. module ('hermodule', []); herModule. service ('herservice', function () {this. her = 1 ;}); // load the service var injector = angular in the two modules. injector (["myModule", "herModule"]); alert (injector. get ("myService "). my); alert (injector. get ("herService "). her );
If multiple modules are loaded, the returned injector can be used to obtain services under multiple modules. In this example, if only myMoudle is loaded, the injector cannot access the services under herMoudle.Note: angular. injector () can be called multiple times, and the newly created injector object is returned each time.
var injector1 = angular.injector(["myModule","herModule"]);var injector2 = angular.injector(["myModule","herModule"]);alert(injector1 == injector2);//false
4. Three dependency declaration methods in angular
Angular provides three ways to obtain dependencies: inference, annotation, and inline.
// Create the myModule module and register the service var myModule = angular. module ('mymodule', []); myModule. service ('myservice', function () {this. my = 0 ;}); // obtain injectorvar injector = angular. injector (["myModule"]); // The first inferenceinjector. invoke (function (myService) {alert (myService. my) ;}); // The second annotationfunction explicit (serviceA) {alert (serviceA. my) ;}; explicit. $ inject = ['myservice']; injector. invoke (explicit); // The third inlineinjector. invoke (['myservice', function (serviceA) {alert (serviceA. my) ;}]);
In the annotation and inline modes, it is recommended that function parameter names be not required. In the inference mode, the parameter names must be consistent with service names. If JavaScript code is compressed or obfuscated, we recommend that you do not use this method.