我注意到一个奇怪的行为。如果我有一个具有input
和focus
回调的focusout
,则嵌套组件只有一个简单的类似于displaySomething
的方法,就会被调用太多次。
仅看一下this stackblitz示例(请注意控制台中的日志消息)。
特别是
中的displayDataContent()
<div>
<ul>
<li *ngFor="let content of data.contents">
{{ displayDataContent(content) }}
</li>
</ul>
</div>
为什么这个函数被调用那么多次?如果我之前没有在其中放置console.log
语句,我不会注意到这种行为。
如何避免这种情况?我不明白为什么会首先发生这种情况。
答案 0 :(得分:1)
这是预期的行为。这是绑定到模板的数据,并且Angular的更改检测周期检查绑定的属性,以查看其值是否已更改,并且需要在组件或其视图中进行更新。由于这是一种方法,因此Angular可以检查其值是否已更改的唯一方法是调用它,并将新结果与当前值进行比较。
在许多文章中,您经常会看到这种行为被认为是不好的做法,因为多个半昂贵的方法调用会严重损害页面的速度。但是,一种非常简单的方法几乎不需要计算就可以返回一个值,与使用getter或本机值访问器几乎没有什么不同,因此这种做法并不总是错误的……但是,它仍然(稍微)在堆栈上进行更多工作,并将阻止更改检测,直到方法完成。
由于这个原因,通常被认为是最佳方法,或者在绑定之前将值取消包装到组件属性,或者使用管道。如果值将由于组件外部的事件而改变,则使用Observable
和async
管道的Observable
是最可取的模式。 ChangeDetectorRef
的排放意味着检测到反应性变化,而不是轮询。
您还可以策略性地告诉Angular关闭或限制整个组件的变更检测,然后在需要时使用gulp.src([
// vendor folder first
path.join(folder, '/vendor/**/*.js'),
// custom js after vendor
path.join(folder, '/**/*.js')
])
手动运行变更检测周期...虽然这总体上可以加速变更检测是Angular作为框架最吸引人的事情之一,通常是将控件转换为Angular的更好的设计选择。