angular开辟中题目纪录--启动历程初探

公司一些治理背景的前端页面,运用的是angular开辟的,得益于angular的双向绑定和模块化controller使得构建pc端的CRUD运用简朴了不少。angular有许多比较难明白的观点,上手起来没有vue简朴,不过对着模板项目、看看tutorial、浏览项目代码再模仿项目代码写一些营业功用照样可行的。假如想要用到一些高等功用那就要下肯定工夫进修才行。

碰到的题目

在开辟的时刻碰到了这么一个题目,先上代码

'use strict';
var domain = 'http://localhost:1337'; //开辟环境下的效劳端地点,
var MY_DOMAIN = 'http://production.com'; // 天生环境的网站地点
angular.module('adminApp').run(function($location) {
    if ($location.host() !== 'localhost') {
      domain = MY_DOMAIN;
    }
  })
  .constant('myConfig', {
    host: domain,
    domain: domain,
    api: this.domain + '/admin', //项目中要求效劳端异步猎取数据的接口
 }

上面的代码,乍一看是自动切换临盆和开辟环境的效劳端地点,但是当布置以后发明这段代码彷佛并没有见效,domain始终是’http://localhost:1337‘,并没有经由历程推断host而被赋值为MY_DOMAIN。
在没有对angular的运转机制有所相识的情况下,我会以为代码会自上而下的实行,如许在.constant的代码实行之前,会先实行.run内里的要领。但是代码的终究实行效果表明,.constant内的代码运转应该是先于.run内里的代码。因而浏览angular的文档来找找缘由。

constant和run是什么

angular比较中心的一个观点就是依靠注入,angular的模块化以及模块间的依靠治理都是基于此的。而这些依靠都是从哪里来的或许怎样自建一些依靠呢?这就须要本身定义一些Providers,angular供应了5种Provider recipe(恕我不晓得怎样翻译这个观点):factory、service、value、constant、provider,这里我们只体贴constant。官方文档形貌constant是用来为设置阶段(config phase)和运转阶段(run phase)供应没有依靠的简朴对象,也就是说我们在constant内里定义的对象或基础范例可以在run和config内里注入:

angular.module('adminApp')
  .constant('myObj', {
    name: 'angular'
 })
 .constant('myStr', 'hello')
 .config(function(myObj) {
    console.log(myObj.name) // angular
 })
 .run(function(myStr) {
    console.log(myStr) //hello  
 })

那什么是运转和设置阶段呢?官方文档如许说:

A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consists of a collection of two kinds of blocks:
1.Configuration blocks – get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
2.Run blocks – get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.

上面引见angular的模块实际上是设置块和运转块的鸠合,这些blocks是在angular的启动(bootstrap)历程中被添加进模块的。Configuration blocks和Run blocks可以明白为行列,一个模块可以写多个.run和.config,末了被顺次添加进响应的blocks中。config只能注入provider 和constant recipe,run只能注入实例(不是providers)和constant recipe。但我测试value recipe是可以注入到run的,好吧我认可angular文档真的不好明白。

总之我以为就一句话概略就是:constant可以明白为是angular用来为模块供应可注入的一切模块同享的常量(无依靠的简朴对象或范例),并且在config和run阶段之前定义好的。 (仅仅是个人明白)

实行递次

上面说了constant应该是在run之前被实行,可这只是顺序运转的表象,为何会如许呢,因而就搜刮了一下angular的启动历程,个中这篇对启动历程的[源码剖析](http://liuwanlin.info/angular…),给了我一些启示。
内里引见了setupModuleLoader要领,该函数返回了一系列的API,用于Angular构造模块,注册指令、效劳、控制器。
《angular开辟中题目纪录--启动历程初探》
可以看到适才前面引见的configBlocks和runBlocks,这里要申明的是constant运用了unshift,将constant插进去到行列的首部,这也就保证了constant在设置、运转之前可以在其他一切块中被注入。

再看下loadModules要领,这个要领用于加载模块,即返回须要运转的块,之前提到的constant和provider实在就是被加入了invokequeue当中,这只是注册并没有实行,在这个函数中挪用runInovequeue才真正实行天生实例,也可以看出config是在run之前运转的:
《angular开辟中题目纪录--启动历程初探》

解决题目

上面大抵诠释了一下constant先于run被实行的缘由,这也是文章最最先写的代码没有根据预期实行的缘由。晓得了缘由又晓得.run内里可以注入已定义的constant,那末我们就晓得只需轻微改一下代码就可以获得想要的效果:

'use strict';
var domain = 'http://localhost:1337'; //开辟环境下的效劳端地点,
var MY_DOMAIN = 'http://production.com'; // 天生环境的网站地点
angular.module('adminApp').run(function($location, myConfig) {
    if ($location.host() !== 'localhost') {
      myConfig.domain = MY_DOMAIN;
      myConfig.api = myConfig.domain + '/admin'; //这里不要希冀myConfig内里的domain会跟随者domain变量的变化而变化,对象一旦竖立,它的属性值就是牢固的了,想修正只能经由历程对象接见属性修正。
    }
  })
  .constant('myConfig', {
    host: domain,
    domain: domain,
    api: this.domain + '/admin', //项目中要求效劳端异步猎取数据的接口
 }

参考文档:

angular providers
angular modular
dependency injection
AngularJS中几种Providers(Factory, Service, Provider)的区分
AngularJS源码浏览1:启动历程

    原文作者:布利丹牵驴子
    原文地址: https://segmentfault.com/a/1190000007176887
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞