Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 何时以及为什么使用';勾选';在角2?_Angular - Fatal编程技术网

Angular 何时以及为什么使用';勾选';在角2?

Angular 何时以及为什么使用';勾选';在角2?,angular,Angular,我已经看到在Angular 2组件类中使用了以下内容: setTimeout(()=>{}, 0); 也就是说,0秒后调用空函数。我知道这与Javascript事件模型有关,但并不完全理解它 请解释Angular 2中何时以及为什么会这样做,使用一个小的现实世界的例子和一些代码片段我记得很久以前问过这个问题。在一个名为angular flexslider的github repo中得到的响应是,它在某种程度上是$(document.ready(function(){…}))的组件级替代品

我已经看到在Angular 2组件类中使用了以下内容:

setTimeout(()=>{}, 0);
也就是说,0秒后调用空函数。我知道这与Javascript事件模型有关,但并不完全理解它


请解释Angular 2中何时以及为什么会这样做,使用一个小的现实世界的例子和一些代码片段

我记得很久以前问过这个问题。在一个名为angular flexslider的github repo中得到的响应是,它在某种程度上是
$(document.ready(function(){…}))
的组件级替代品

Angular在加载页面后操作DOM。当CPU有点忙时,有时可以看到页面加载后角度表达式更新。timeout函数确保代码在angular完成文档处理后零毫秒内运行

我从来没有这样做过,现在有了组件生命周期挂钩,我无法想象你还会需要这样做(也就是说,如果你真的需要的话)。但从角度来说,这就是我看到的原因。我还可以说,我看过很多由工程师编写的Angular代码,你对这些代码有很高的信心(就他们对Angular的知识而言),而且从未见过有人这样做

此外,这也是确保要运行的代码放在当前事件循环队列末尾的一种方法。这通常是为了表现。我曾经为“无限滚动”列表做过如下操作(现在都是RXJ、Observables等)。考虑这个代码:

var res = []
function response ( d ) {
  var chunk = data.splice ( 0, 1000 );

  res = res.concat ( chunk.map ( ...do something ) );

  if ( data.length > 0 ) {
    setTimeout ( () => { response ( data ) }, 0 );
  }
}
因为您通过
setTimeout
递归调用
response
来处理块,即使它的间隔为0,您也是分批执行的,并且每个批都将在当前作业队列的末尾进行处理(而不是在事件队列中建立一个事件堆栈,这将导致阻塞)

使Angular对整个应用程序运行更改检测,如


zone.js修补异步API(
addEventHandler
setTimeout
,…),并在回调完成后运行更改检测。

我将添加Gunter的答案,因为它目前很小

他说:

setTimeout(()=>{},0)使Angular对整个应用程序运行更改检测

这是因为
setTimeout
方法被猴子补丁,被angular拦截,一旦拦截,angular就会触发更改检测。换句话说,每次
setTimeout
都被称为更改检测

可以这样做:

const temp = window.setTimeout;
window.setTimeout = (...args) => {
    temp(...args)
    angular.triggerChangeDetection(); // or w.e they use
}

因此,0是为了使更改检测立即发生,而空函数是因为我们不想做任何事情。

您能提供您看到这一点的地方吗?我想他想知道您为什么要将空回调设置为零间隔。箭头函数部分是偶然出现的。如果我不知道这段代码是在什么环境下使用的,很难说。OP函数是空的,所以它没有什么意义。当时没有生命周期挂钩吗?这难道不能与不做任何事情只做一次滴答声传递有关吗?我已经修改了我的答案,使其更完整,不仅仅是角度。我最终不知道为什么有人会在零间隔上设置一个空回调。其效果只是在作业队列的末尾放置一个空回调。我甚至不确定JS运行时在优化方面会做什么(它会或多或少地忽略它吗?)。我还可以说,我看过很多Angular代码,其中很多代码都是由你希望了解他们在框架中的方式的人编写的。我从来没有见过有人在0间隔超时的情况下执行空回调。似乎gunter发现了原因:P6只是在一个项目中需要它,我必须在DOM更新后立即计算
scrollTop
ngAfterViewInit
给出了错误的值,修复为0ms
setTimeout
.Hmm。“滴答声”是角度框架的一部分,所以您希望它以某种方式表现。但是setTimeout只是简单的ol'js,除了在作业队列上放置回调之外,它什么也不做。您似乎在暗示只有在有作业队列要处理的情况下才能保证运行更改检测,所以为了确保它触发,您只需在浏览器作业队列上转储一个空回调?如果是真的,那听起来像是A)一个巨大的框架问题和B)一个解决该问题的黑客方法。我对此持怀疑态度(因为任何人看到0间隔的CB为空都会如此)。@TimConsolazio检查我的答案,我不能100%确定tho@TimConsolazio不知道你说的“两个”是什么意思
ApplicationRef.tick()
setTimeout(()=>{},0)
是等效的(如果
setTimeout(…)
在角度范围内运行,因此在一个区域内),我同意(我避免像瘟疫一样的超时)。但许多人没有,正如OP所说,他在组件中看到了这一点。如果这成为组件开发人员普遍接受的一种实践,从而进入一个大型代码库,在这个代码库中您需要频繁地重用代码,那么这可能是一个问题。当然,很多人都不知道这一点(因为一开始这似乎是一个冒险的想法),并且会对发现这一点感到震惊(我也是)。谢谢你的文档。你也可以在区域外做(根据区域api)。但是,你必须知道这一点。我参加过由Angular团队主持的Angular 2会议,没有人提到过这一点,尽管他们确实讨论了zones是如何成为新摘要的。为了完整起见,这似乎是准确的。setTimeout的行为已被无形地更改。对于考虑到这一点的代码(这样就知道何时在区域外运行代码),这可能没问题。但进口LIB等,对这些有什么影响?每次中场休息时,不管
const temp = window.setTimeout;
window.setTimeout = (...args) => {
    temp(...args)
    angular.triggerChangeDetection(); // or w.e they use
}