angular2-7中的变化监测
最近做公司新项目用的angular7,中碰到了一个很头疼的问题在绑定对象中的数据改变时,页面视图没有跟新,需点击页面中的时间元素后才会更新。以前使用angularJs也经常碰到类似情况,这种时候一般的方式使使用脏检查(Dirty checking)让angularJs检查绑定到视图上的数据来实现对页面数据的刷新。
接触angular7时间还不久,angular高版本中提供了一系列组件的生命周期钩子,能在组件生命周期的各个阶段,对组件进行操作,监测组件中输入数据的变化,基本少很少碰到需要用到类似于angularJs中脏检查的情况。一直以为在高版本中的angular中已经不会出现需要脏检查的情况了,可是该来的迟早会来。
在项目中由于使用了公司的自己的播放插件,angular自身的事件注册机制无效,只能使用原生的js位视频播放插件注册点击事件。实现点击插件后通过插件绑定的回调函数将该分屏信息发送给父组件,在父组件中通过对父组件绑定对象中的属性值的改变来改变父组件的样式。
// 插件中的代码片段
ngAfterViewInit() {
// 页面视图初始化完成之后为视频播放插件添加点击事件
this.videoObj = document.getElementById('obj' + this.screen.id);
this.videoObj.addEventListener('click', () => {
this.selectThisScreen(this.screen);
}, false);
} private selectThisScreen(screen) {
// 输出该分屏对象,输出给父组件
this.screenSelected.emit(screen);
} // 父组件中的代码片段
private selectedScreen(screen) {
this.videoLayoutService.selectedScreen(screen, this.videoLayoutOutput);
} // videoLayoutService 片段
this.screensConfig.screens.map(item => {
if (item.id === screen.id) {
item.selected = !item.selected; // 这是想要更新的值!!
if (item.selected) {
videoLayoutOutput.emit({
device: {
id: screen.device.Id,
code: screen.device.SerialNo,
selectedCamera: screen.device.SelectedCamera
}
});
} else {
videoLayoutOutput.emit({ device: { id: null, code: null, selectedCamera: null } });
}
} else if (item.id !== screen.id) {
item.selected = false;
}
});
可是由于插件事件绑定只支持原生js的方式,没有有使用angular自身的事件绑定机制(已测试,在不适用该插件的条件下,使用angular自身的事件绑定机制view层能够监测到数据的跟新),view层没能监测到绑定数据的变化。在尝试了各种方式,和各种生命周期钩子后(甚至测试了ngDoCheck)都没有效果后都没能达到想要的效果,这时我想会不会现在angular7中也存在和angularJs中数据更新视图没更新的一样问题,如果是那也应该有类似与$scope.$applay()这样类似的方式来解决这个问题。
然后去查了一下官网文档,在文档中没有直接找到类似方法。后去网上找,后来在篇文章中发现了NgZone这个服务(具体哪一篇忘记记录了,找的博客太多了后来忘记了),然后去官网查了查用法。
官网文档中使这样描述的:An injectable service for executing work inside or outside of the Angular zone.(用于在Angular区域内外执行工作的可注入服务。)看的云里雾里。。然后又看下面的说明。
The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that don't require UI updates or error handling to be handled by Angular. Such tasks can be kicked off via runOutsideAngular and if needed, these tasks can reenter the Angular zone via run.
大概是说这个服务最常见的用途是在启动一个或多个异步组成工作是优化性能时使用,这些任务不由angular处理UI更新或错误处理(感动终于找到问题所在了!因为插件使用原生js进行事件绑定,没有走angular自身的事件绑定机制导致了angular框架不处理UI更新。。所以需要在这里使用NgZone这个服务),这些任务可以通过runOutsideAngular启动,如果需要,这些任务可以通过run重新进入Angular区域。
也就是说我现在可以使用NgZone服务的提供的run()方法将这个事件加入到angular的UI更新管理区域中,一切引刃而解。
在父组件中注册NgZone服务使用run()方法
// 父组件中的代码片段
constructor(private videoLayoutService: VideoLayoutService, private zone: NgZone) {
}
private selectedScreen(screen) {
this.zone.run(() => {
this.videoLayoutService.selectedScreen(screen, this.videoLayoutOutput);
});
}
最后来简单说明下NgZone中的几个方法的使用
run():在Angular区域内同步执行fn函数,并返回函数返回的值。通过run运行函数允许您从在Angular区域之外执行的任务(通常通过runOutsideAngular启动)重新进入Angular区域。在这个函数中调度的任何未来任务或微任务都将在Angular区域中继续执行。如果发生同步错误,它将被重新抛出,而不是通过onError报告。
runTask():以任务的形式在Angular区域内同步执行fn函数,并返回函数返回的值。通过run运行函数允许您从在Angular区域之外执行的任务(通常通过runOutsideAngular启动)重新进入Angular区域。在这个函数中调度的任何未来任务或微任务都将在Angular区域中继续执行。如果发生同步错误,它将被重新抛出,而不是通过onError报告。
runGuarded() :与 run() 相同,除了同步错误是通过onError捕获和转发的,而不是重新抛出。
runOutsideAngular() : 在Angular的父区同步执行fn函数,并返回函数返回的值。通过runOutsideAngular运行函数可以让您逃离Angular的区域,并做一些不会触发Angular变化检测或受制于Angular错误处理的工作。在这个函数中调度的任何未来任务或微任务都将在Angular区域之外继续执行。使用run重新进入Angular区域并执行更新应用程序模型的工作。
angular2-7中的变化监测的更多相关文章
- Angular开发实践(五):深入解析变化监测
什么是变化监测 在使用 Angular 进行开发中,我们常用到 Angular 中的绑定--模型到视图的输入绑定.视图到模型的输出绑定以及视图与模型的双向绑定.而这些绑定的值之所以能在视图与模型之间保 ...
- 深入理解Angular2变化监测和ngZone
转载自GitHub JTangming : https://github.com/JTangming/tm/issues/4 Angular应用程序通过组件实例和模板之间进行数据交互,也就是将组件的数 ...
- VueX中state变化捕捉不到_getters监测不到state的变化
原因 可能有多种原因, 现在我说一下我碰到的一种情况: state种有一个变量叫state,它是一个json对象, 可把我害惨了.因为他这个json长这个样: messageBox:{ friendI ...
- js 实时监听input中值变化
注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...
- 第50讲:Scala中Variance变化点
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- [转] Express 4 中的变化
http://www.cnblogs.com/haogj/p/3985438.html 概览 从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在 ...
- iOS中让Settings Bundle中的变化立即在App中反应出来的两种方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 为了能够在Settings Bundle中的变化在进入App后 ...
- ITMS-SERVICES://方式安装IPA在IOS 7.1中的变化
转:https://laoyur.com/?p=414 iOS7.1中,通过itms-services://方式安装ipa已经发生了改变,.plist文件必须是https://的,.ipa文件的链接则 ...
- Angular2+URL中的 # 引发的思考
1.先分析 # 的作用 1.1. # 的涵义 #代表网页中的位置.其右面的字符就是该位置的标识符.比如,http://www.example.com/index.html#print就代表网页inde ...
随机推荐
- Java虚拟机-垃圾收集器
垃圾收集器(Garbage Collection, GC)的诞生引导出了三个问题: 哪些内存需要回收? 什么时候回收? 如何回收? 对于线程独占的三个区域(程序计数器.虚拟机栈.本地方法栈)不用过多的 ...
- string to int
problem describe: given a string , first find the first word which is not white space;then there wil ...
- First Scala
注意的两点: 1. Class or Objcect 在Scala把类和对象明确的分开了. Class相当于模板:Object是Class的实现. 2. main 要测试代码必须使用main def ...
- HTML 标签小细节
简书地址:https://www.jianshu.com/p/03a23aa28a34 今天重新学习了一下HTML中标签的用法,补充并记录一下自己新学到的知识. a中的href href Contai ...
- Spring Boot 发送邮件
需求 最近因为业务的变更,需要对老用户进行发送邮件处理.目前市面上也有很多代发邮件的接口,可以接入.由于量不是特别大,放弃了这个途径.改用我们自己通过 smtp 发送邮件来处理. 技术选择 Java ...
- linux 文件传输 SCP
SCP :secure copy (remote file copy program) 也是一个基于SSH安全协议的文件传输命令.与sftp不同的是,它只提供主机间的文件传输功能,没有文件管理的功能. ...
- 【转】Javascript错误处理——try…catch
无论我们编程多么精通,脚本错误怎是难免.可能是我们的错误造成,或异常输入,错误的服务器端响应以及无数个其他原因. 通常,当发送错误时脚本会立刻停止,打印至控制台. 但try...catch语法结构可以 ...
- 功能强大的swagger-editor的介绍与使用
一.Swagger Editor简介 Swagger Editor是一个开源的编辑器,并且它也是一个基于Angular的成功案例.在Swagger Editor中,我们可以基于YAML等语法定义我们的 ...
- capwap学习笔记——初识capwap(五)(转)
3. CAPWAP Binding for IEEE 802.11 ¢ CAPWAP协议本身并不包括任何指定的无线技术.它依靠绑定协议来扩展对特定无线技术的支持. ¢ RFC5416就是用来扩展CAP ...
- UIAlertControl的使用对比与UIAlertView和UIActionSheet
1.UIAlertVIew以-(void)show的方法显示: - (void)viewDidLoad { [super viewDidLoad]; //UIAlertView的使用 [self sh ...