依赖注入和动态组件的WWH(What Why How)

动态组件

问题1:动态组件和我们写的ngIf选择器有啥区别并且优势在哪里?

模板选择器直接实例化组件:

4d9a5355865cd54eecf3a488dd5ebef8b31.jpg

解释:根据已创建的组件工厂进行组件实例化,无须动态生成宿主元素(标签)

 

动态组件(工厂模式实例化组件)

10e20f5c746aace644e70ee749a9ebf21fb.jpg

解释:根据已经声明的组件(静态类d.ts)创建组件工厂再进行组件实例化,宿主元素(标签)通过Host文件生成

 

答:

先说场景:

(1)NG官网的例子一个广告位需要多个不同布局的页面进行切换,如果用ngIf,你就只能写死多个模板在父组件里(静态)。

(2)tab页切换,可以用上图动态组件生成的例子;(scm系统和wms系统的tab页看上去是路由锚点控制页面切换,但实际也是披着动态组件的羊毛)

两者对比:

(1)展现方面:没任何差别

(2)工作量:两者其实没什么差别,但同在一个父组件下基本都是传相同的参数值,那么你宁愿一个个写在模板上,还是写在方法里一劳永逸?

(3)性能:ngIf——我第一时间就想到了ngIf带来的注释模板436c644c0f0e967157f5785da7dc231bc61.jpg,页面的变化都要进行变化检测,模板有多个ngIf模板就会多次判断(强行解释);其次这种懒加载方式能减少bundle的体积,加快首屏渲染速度
    子问题1:enterComponents和声明组件区别? 答:declarations——通过模板的selector创建组件,即声明并创建;entryComponents——声明不创建,等到用的时候才通过离线模板编译器(OTC)根据entryComponents List的内容编译已声明的组件创建工厂,Angular使用entryComponents来启用“tree shaking”,即只编译项目中实际使用的组件,而不是编译所有在ngModule中声明但从未使用的组件,enterComponents在ng里有三种表现形式,

 

扩展:

e0bb1104b53c172da7c6fa39f7ffbf116c5.jpg

645400c5c0a819a2cd1fabb052f7005b92c.jpg

一句话分析这张图片:ng的组件都是通过工厂函数(ComponentFactory<comp>)实例化出来,ngFactory.js文件负责装载组件模板及变化检测代码片段等静态数据,变量早已经在编译过程前开辟好内存空间,一切渲染过程都是以此为媒介。剩下的就是coder的选择是否用动态组件的方式加载,如果选用动态组件方式必定经过entryComponents的记录,当页面要加载这个组件时会OTC编译声明好的组件同时创建ngFactory.js 和 _Host_[x].ngFactory.js,前者渲染页面(考虑IOS和Android)后者负责生成宿主元素,这个就是一个动态组件编译过程。

 

其他:动态组件考点不止这些,还有装饰器@XXX、元数据的传入可以参考 Implementing custom component decorator ,

typescript的decorator是如何被编译的

 

问题2:ng的依赖注入在软件开发解决什么?

答:依赖注入(Dependence Inject)是控制反转(Inversion of Control 后)的行为。

控制反转——好莱坞的法则:“don‘t call us, we‘ll call you”。

4591e172679e3f1d6fc17f7b07030ff238d.jpg紧耦合,谁也不能缺少谁,对象或者模块间通过互new的形式存在

abf585b32f51c86ce0f3a89580b39f3362f.jpg实际场景,复杂且不好管理。

537b2f01c833fef1f594931dd774eb83730.jpg引入第三方把相应的对象/类(ng以服务形式存在)统一管理,并按需注入

150b6da3b514ab994b604b8e9738a68a45d.jpg最后,达到解耦的理想状态

 

问题3:依赖注入不仅仅是调用服务,实战还有更多新玩法。

概念篇——1、创建服务过程选择@Injectable、@NgModule 还是 @Component ?

2、provider入口API及各种提供商(useClass比较常见,适用于内部固定,外部变化多。useFactory对于权限控制即时变更状态场景有用)

3、每个组件创建一个注入器实例,服务实例在应用中是注册多次还是仅有一次,是根据注入形式不同前者是@Component.provider后者是AppModule.provider (举例:多种编辑会话,每个组件需要一个特定的服务进行管理表单的新值和旧值,这种情况必须使用@Component.provider,你可以理解为AppModule.provider注册的就只有一个对象(单例),根模块的提供商是向下传递到有需要用到该服务的组件中,而@Component.provider是为每个组件实例化独立的服务)

实践篇——1、组件可以通过注入器,把自己注入到子组件上(服务=类)

2、类-接口写法{provider: virtual, useClass: realClass},为了节省内存,同时作为Token而存在

3、出现引用循环,立即想到[{ provide: Parent, useExisting: forwardRef(() => AlexComponent) }]

4、仅找上一级的注入器服务添加@Host() 在服务创建前写 @Host() private heroCache: HeroCacheService,防止服务没找到用@Optional()

 

疑问:angular既然选择了AOT编译,那么离线模板编译器(OTC)在客户端是以什么形式存在?代码片段?

 

动态组件模块相关文章

angular2(4) 中动态创建模块和组件的两种方案

[译] 关于 Angular 动态组件你需要知道的

Angular进阶:Angular编译机制(AOT、JIT)

Implementing custom component decorator 

30行代码让你理解angular依赖注入:angular 依赖注入原理

ioc-demo简单例子

转载于:https://my.oschina.net/u/2949632/blog/2052376

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值