Angular-多级配置搞事情啦
栏目: JavaScript · 发布时间: 5年前
内容简介:input组件的方式,可以扩展为依靠服务在业务模块中进行配置,以达到每个模块所用的同一个公共组件拥有不同的交互。但经过具体实践发现,在惰性加载模块进行配置是可行的;在急性加载模块配置是会出事的!
上一篇文章写到:
input组件的方式,可以扩展为依靠服务在业务模块中进行配置,以达到每个模块所用的同一个公共组件拥有不同的交互。
但经过具体实践发现,在惰性加载模块进行配置是可行的;在急性加载模块配置是会出事的!
结合官网的这篇文档可以一窥究竟: Angular - 多级依赖注入器 ,可以从“元素注入器”读起。 那其实有一句挺有意思的:
在不同层次上重新配置一个或多个提供商的能力,开启了一些既有趣又有用的可能性。
关键
那是时候展现真正的技术了。完整代码
预备知识
服务提供商
做个比喻:打电话可以视为电信提供的一个服务,那么电信就可以视为打电话这个服务的提供商。假如就电信这么一个公司,没有它就没法使用打电话的服务。那么需要使用服务就需要服务提供商。
再经过层层“代理”,模块可以提供服务,组件也可以提供服务。它们在各自的范围内,提供服务。
服务的分类
以下示例均采用可以摇树优化的方式提供服务;组件提供的除外,因为一般上,组件会需要使用服务的方法或数据,若采用此方式,则会造成循环依赖。
建议:将服务放到最顶层的业务模块或组件中提供,在其子组件中,通过注入器冒泡的特性去获取该服务的实例或方法或值。
1.单例服务
在 Angular 中有两种方式来生成单例服务:声明该服务应该在应用的根上提供。把该服务包含在 AppModule 或某个只会被 AppModule 导入的模块中。
// 前者 @Injectable({ providedIn: 'root' }) // 抽离core模块是目前看到的官网最佳实践 @NgModule({ imports: [ CommonModule ], declarations: [], providers: [ShareModuleConfigService], }) export class CoreModule { } @NgModule({ imports: [ CoreModule, // .... ], declarations: [AppComponent], bootstrap: [AppComponent], providers: [] }) export class AppModule { } 复制代码
2.模块级服务:
@Injectable({ providedIn: EagerlyLoadedModule })复制代码
3.组件级服务
@Component({ selector: 'app-index', templateUrl: './index.component.html', styleUrls: ['./index.component.css'], providers: [IndexService] })复制代码
样例
文件夹结构。子模块默认页IndexComponent
1.准备工作
(1)根组件中拥有helloComponent
(2)各子模块的Index.component.html内也有helloComponent
(3)share模块中的helloComponent将使用ShareModuleConfigService内的值进行显示
export class HelloComponent implements OnInit { @Input() txt: string; constructor( // 可选的服务 @Optional() private config: ShareModuleConfigService ) {} ngOnInit() { this.txt = this.config ? this.config.helloCompTxt : null; } }复制代码
(4)我们还有一个由coreModule提供的单例服务ShareModuleConfigService(将share模块可配置的集中于此,供各模块灵活配置),修改此配置来达到自定义share模块的某些展示或交互。
@Injectable() export class ShareModuleConfigService { helloCompTxt: string; data = [1]; constructor() { console.log('ShareModuleConfigService constructor'); } }复制代码
(5)均通过useValue的方式简单的配置一下:
providers: [ { provide: ShareModuleConfigService, useValue: { helloCompTxt: '惰性模块搞一下hello组件', data: [4] } } ]复制代码
(6)我们将在页面上看到在不同层级下的helloComponent的展示效果。
2.惰性加载模块内配置
首先将样例代码中AppModule中imports中注释掉EagerlyLoadedModule,将会看到这样的运行效果。
根组件展示了ShareModuleConfigService的初始值
然后,点击”去懒加载模块(惰性加载模块)“,将会看到:
经过惰性模块修改后,初始值被改变了,实现了模块级配置
再来修改下lazy-loaded中的Index.component.ts,我已写好,只要把注释去掉即可。那么将会看到这样的效果。
组件的配置,”覆盖“掉了模块内的配置
还有一点值得注意:根组件所使用的值未变化,可以理解为惰性模块将单例服务又实例化了一次。将两者完全隔离开了。由此可以达到各个惰性模块内拥有自己的配置,以将share模块内的组件、指令、管道实现不同的交互或功能。
3.急性模块内修改配置
一如之前的流程,但一开始将会看到不一样结果。去掉AppModule中之前的注释。将急性模块加载到应用里来。
根组件的值直接被修改了
然后,将AppModule中的将CoreModule放在最后
根组件的值并未发生改变
是不是很神奇?其实官方已经给出解释,让我们来看一看。
根AppModule导入了CoreModule,并把它的providers添加到了AppModule的服务提供商中。 特别是,Angular 会在@NgModule.providers前面添加这些导入的服务提供商。 这种顺序保证了AppModule中的服务提供商总是会优先于那些从其它模块中导入的服务提供商
原文在此: angular.cn/guide/singl…
由此,若是想保证单例服务的唯一性,就必须将CoreModule置于所有其余模块的后面,以免被急性模块干扰。
子组件的配置就不再提了,跟惰性模块是一样的。说了这么多,本文提到的点还是蛮多的。现在来总结一下:
1.惰性模块若需配置share模块:利用惰性模块新建实例的性质,在模块内直接配置。
2.急性模块若需配置share模块,则不能在模块内进行配置,要么会被单例服务覆盖,要么会覆盖单例服务。所以可以将配置提到该模块的根组件内以达到此效果。
3.由急性模块中的组件修改单例服务的值,根模块中的值其实并未变化的现象。可以看出,在Angular中值的流动其实是从上到下单向流动的。就像一颗倒置的树,营养(数据)从根(根组件)传递到各个树枝上。
参考:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C算法(第二卷:图算法)(第3版)
塞德威克(Sedgewick Robert) / 周良忠 / 第1版 (2004年1月1日) / 2004-4 / 38.0
《C算法(第2卷)(图算法)(第3版)(中文版)》所讨论的图算法,都是实际中解决图问题的最重要的已知方法。《C算法(第2卷)(图算法)(第3版)(中文版)》的主要宗旨是让越来越多需要了解这些算法的人的能够掌握这些方法及基本原理。书中根据基本原理从基本住处开始循序渐进地讲解,然后再介绍一些经典方法,最后介绍仍在进行研究和发展的现代技术。精心挑选的实例、详尽的图示以及完整的实现代码与正文中的算法和应用......一起来看看 《C算法(第二卷:图算法)(第3版)》 这本书的介绍吧!