5. 测试用例定义的[id]变量,在组件的 ngOnInit()生命周期钩子拿不到
解决方法:在 ngAfterViewInit()生命周期钩子可以拿到。
用户写宿主 id 三种方式:
1)给 HTML 属性 id 赋字符串
2)给 HTML 属性 id 赋变量
3)给 DOM 属性 id 赋变量
组件开发读写宿主 id 的三种方法:
1)读 HTML 属性 id(左右/上下滑动可查看全部代码)
2)写 HTML 属性 id
3)读写 DOM 属性 id(左右/上下滑动可查看全部代码)
6. 函数作为入参时候,函数尽量写成箭头函数形式
组件开发过程过需要修改或者读取组件属性或者方法时候,一定要写成箭头函数形式,不然会出现 this 指向问题。
比较常见的 2 种应用。
1)定时器:(左右/上下滑动可查看全部代码)
let timer = setInterval(() => {
startDist += motion.step * dir;
topy+= motion.step * dir;
if (Math.abs(startDist - startPoint)>= motion.distance) {
clearInterval(timer);
timer = null;
}
}, 1);
2)事件监听:(左右/上下滑动可查看全部代码)
document.addEventListener(‘mousemove’, this.mouseMoveHandlerFn);
private mouseMoveHandlerFn = ($event) => {
const option = this.config.options;
}
7. 组件通讯之子获取父的实例
应用场景:组件嵌套,子组件需要用到父组件的属性和方法。
组件嵌套形式如下面代码:
父组件的模板代码如下,父组件嵌套了子组件 app-child。
(左右/上下滑动可查看全部代码)
方案:在 constructor(构造函数)中使用 @Inject()依赖注入父组件。
如下面代码:
并且上面的方式是单例的(父组件下不管有几个子组件,父组件只实例化一次),但是这种方式只能注入一个组件实例。
在实际开发中,例如选择按钮组有多选按钮和单选按钮,这个时候就需要注入多个父组件。用上面同样的方式同时注入 2 个就会报如下错误:
原因如下:
当组件申请一个依赖时,Angular 从该组件本身的注入器开始,沿着依赖注入器的树往上找,直到找到第一个符合要求的提供商。如果找不到就会抛出一个错误。
解决方案:
在 @Inject()装饰前加 @Optional(),如下面代码:
(左右/上下滑动可查看全部代码)
解决原因:
当 Angular 找不到依赖时,@Optional 装饰器会告诉 Angular 继续执行,Angualr 会把此注入参数设置为 null(而不是默认的抛出错误的行为)。
8. 组件生命周期总结
如上图,为组件初始化各个生命周期执行顺序。其中紫色的生命周期只在组件初始化执行一次,绿色的会执行多次。
1)ngOnChanges 频率较低,仅监听用户对 @Input 变量的改变。注意:监听不到组件开发者在代码中对变量更改。可以考虑使用 @Input set 访问器方式,监听变量,所有改变都可以监听到。
2)ngDoCheck,触发频率超高。angular 自身监视[ngclass]数组变化,是放在这个生命周期。使用了 IterableDiffers 机制。其他什么情况适合放在这里,暂时不太清楚。
3)ngAfterContentChecked,ngAfterViewChecked 相对频率低。我们目前代码监听 Dom 属性变化,暂时放在这里了。不知道有没有更好办法监听 Dom 属性变化。
注意:如果在 ngAfterViewChecked 里面,改变了模板中使用的变量,此变量不一定能及时更新到试图。需要强制刷新 this.changeDetectorRef.detectChanges();
4)想监听数组和对象属性变化,angular 内部使用了 IterableDiffers 和 KeyValueDiffer。参考[ngClass]源码。
本转载自 Think 体验设计公众号。
原文链接:https://mp.weixin.qq.com/s/4bfahysRdH9pVST_UZ4cXg
评论