问题标签 [angular-changedetection]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
angular - Angular 7 变更检测:NgZone.onMicrotaskEmpty 的问题
我在 Angular 应用程序中使用 chart.js 并使用来自 API 端点的数据绘制图表。
上面的代码在 angular 4 上运行得很好,但是在升级到 angular 7 之后,我不得不将我的代码更改为
因为.first
在角度 7 中消失了。这增加了 CPU 利用率并使应用程序崩溃。已ngZone.onMicrotaskEmpty.first
在我的应用程序中广泛使用,我不知道如何正确处理更改检测。我也尝试过这种方式
但没有运气。任何人都可以帮助我吗?谢谢
angular - 从 runOutsideAngular 上下文调用 ChangeDetectorRef.detectChanges。可以吗?
ChangeDetectorRef.detectChanges
从NgZone.runOutsideAngular
上下文中调用可以吗?我有通过WebSocket
. Websocket 数据流非常密集,因此我将其包装成NgZone.runOutsideAngular
. 各种服务订阅 websocket 数据,对其进行处理并报告它们自己的事件 ( Observables
)。它们在角度区域外触发。Angular 组件订阅它们并在事件处理程序(观察者)中调用ChangeDetectorRef.detectChanges
. 在大多数情况下,这可以正常工作。但在某些情况下,它会导致麻烦:ngFor 可能会在角度区域之外创建新元素/组件。此类组件的事件处理程序将触发超大角度。我知道我可以将它们包装到NgZone.run
调用中,但这会导致我想要避免的全局变化检测。
UPDATE1:我创建示例来演示该问题:
https ://stackblitz.com/edit/angular-5-change-detection-in-runoutsideangular-context
添加一些项目,然后尝试使用x
按钮将其删除。
angular - API调用后Angular组件不更新
我有一个下拉组件,它将模型作为[输入]。
在父母我有:
问题是不更新子组件。所以下拉列表不会更新。我可以看到 viewModel 已初始化。
我已经用一种方式绑定了它 [ this.viewModel.dropdownItems ]
我也在其他地方使用这个下拉组件,所以我知道它可以工作。(不知道api调用虽然不知道我是否在其他地方这样做)
angular - 当 ChildComponent 发生变化时如何监听然后在 ParentComponent 中执行方法?
我正在 Angular 7 中寻找一个干净有效的解决方案,以便在每次子组件更改时执行组件中的方法。
给定一个ParentComponent
渲染 a ChildComponent
,我需要知道什么时候ChildComponent
改变了,然后在ParentComponent
.
通过更改,我指的是视图或子类中任何属性的更改。
谢谢。
angular - 嵌入与 ng-content 子项的不同 ChangeDetectionStrategy.OnPush 行为
我正在调整应用程序的性能并遇到以下差异。请参阅stackblitz以获取实时示例。
带有后缀的组件-on-push
有ChangeDetectionStrategy.OnPush
,而带有后缀的组件-default
有默认策略。
我有两种方法,我将第一种方法命名为“嵌入式”,将第二种方法命名为“ng-content”。澄清如下。
根模板:
其中app-embedded-on-push
s 模板只是“嵌入”了app-embedded-default
组件:
另一方面,app-ng-content-on-push
s 模板将app-ng-content-default
组件投影为ng-content
:
请查看 stackblitz 以获得更好的想法。
期待
由于ChangeDetectionStrategy.OnPush
只有在输入引用发生更改时才检查组件(组件本身及其子级),我的期望是在组件本身及其子级上,更改检测不会被两种方法触发,命名为嵌入和内容投影方法。
现实
使用嵌入式方法,行为符合预期,app-embedded-default
不会触发更改检测。另一方面,通过内容ng-content
投影(app-ng-content-on-push
有人可以解释为什么这是结果行为吗?两种方法的组件树都是相同的,还是我错了?
angular - ngOnInit 上的 Angular 将 false 更改为 true
我有一项服务,其中包含一组选定的 ID。当我初始化一个组件时,我会检查该组件的 ID 在数组中是否存在。但是,Angular 会抛出一个异常,即视图检查后值已更改。
我试过在detectChanges()
之后添加this._checked = true
,试过了markForCheck()
。此外,我尝试将这两种情况移动到不同的生命周期挂钩,但没有成功,只是它开始工作,尽管抛出错误。
angular - 使用模板内的 getter 触发的角度变化检测循环
似乎在模板中使用 getter 会导致 Angular 更改检测进入循环(getter 被调用数百次)。在阅读了大量关于类似问题的文章后,我似乎无法得到明确的答案。
背景资料:
从可维护性的角度来看,我确实相信在模板中使用 getter 是最干净的方法,但似乎因为 Angular 在调用它之前无法知道 getter 值是否发生了变化,它只是一直调用它。到目前为止,我找到了三种选择:
- 停止使用 getter,公开所有属性并直接访问它们
- 将每个 getter 的值存储到组件上的公共属性中并绑定它而不是模板中的 getter
- 将 Angular 的 changeDetection 模式从默认更改为 onPush
对于使用 Typescript 类的好处,选项 1 似乎违反直觉。选项 2 似乎是不必要的代码重复并降低了可维护性,选项 3 需要进行重大重构。
这是一个示例(为说明目的而简化)
模型:
组件.html
组件.ts
将输出以下控制台日志: console.log output
任何人都可以推荐最佳实践来避免在 Angular 中处理复杂模型时出现不必要的循环吗?甚至是调试此类行为的正确方法,就目前而言,我是控制台。记录 getter 方法并观察内存使用峰值。
编辑(答案) 经过更多时间调查,挖掘堆栈跟踪后,我发现无限变化检测循环实际上是由我们注入的名为“Sentry”的服务引起的。显然,当使用触发更改检测的 console.log 时,它会导致问题。在这里找到了一个关于它的 github 问题:github.com/getsentry/sentry-javascript/issues/1883没有找到解决方案(似乎天生不兼容),如果我找到解决方案,将更新。
angular - public get 从 auth 服务返回一个权限布尔值,初始化为 false 并在 NGRX 存储返回值但未定义时修改
我有一个 Angular7 应用程序,我选择在 app.component 中显示一个基于布尔值的按钮,该布尔值定义为:
现在在我的身份验证服务中,我在权限模型之后初始化了 userPermissions,所有权限都标记为“false”。
在 Authentication 上,权限数组被发送到 reducer,并且正在使用 ngrx 存储设置权限。
在服务中,我订阅了该存储值并更新了权限对象。
现在的问题是,身份验证后第一次整个事情崩溃返回:
引用我定义 getter 的行。
但它在任何地方都有定义。我的代码中没有一个地方我没有初始化并使用“false”默认值定义模型变量。
在我处理权限数组的减速器中:
似乎我忘记使用该数组中的权限更新模型,当 for 循环到达时,它使整个状态未定义。
angular - 如何在 Angular 7 中使用 ChangeDetection(视图未更新)?
我不知道如何在我的 Angular 应用程序中使用 Change-Detection。我的方法的目标是,仅当我的表列表中的数据发生更改时才显示更新列表。
目前,当我更改表格列表中的一行时,仅显示第一个数据。在控制台中,我看到了第二个更改的数据,但我的视图没有更改更新列表。
这是我的组件:
和我的观点:
谁能帮我解决这个问题?
angular - ngIf 指令如何改变检测更改周期?
Stackblitz 示例:https ://stackblitz.com/edit/ngif-detectionchange
testToggle
由于绑定到其中的某些属性,我有可以更改其高度的组件。它有兄弟testParent
组件,它是 flex 以获取其余高度,并且它testChild
具有绑定到testParent
高度的子组件。当testParent
*ngIf 指令具有真表达式时,当testToggle
更改绑定到其高度的属性时,我得到:
错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。
在记录组件的生命周期钩子顺序后,我发现了一些奇怪的东西:
显然,正确的示例抛出 ExpressionChanged,因为整个testParent
周期已经结束,之前testToggle
可以更新它的绑定(这会改变它的高度,因此改变testParent
高度)。
我想知道为什么使用 ngIf 动态添加的组件在通过组件树正常继续之前完成其整个生命周期?