问题标签 [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.

0 投票
0 回答
296 浏览

angular - Angular 7 变更检测:NgZone.onMicrotaskEmpty 的问题

我在 Angular 应用程序中使用 chart.js 并使用来自 API 端点的数据绘制图表。

上面的代码在 angular 4 上运行得很好,但是在升级到 angular 7 之后,我不得不将我的代码更改为

因为.first在角度 7 中消失了。这增加了 CPU 利用率并使应用程序崩溃。已ngZone.onMicrotaskEmpty.first在我的应用程序中广泛使用,我不知道如何正确处理更改检测。我也尝试过这种方式

但没有运气。任何人都可以帮助我吗?谢谢

0 投票
1 回答
313 浏览

angular - 从 runOutsideAngular 上下文调用 ChangeDetectorRef.detectChanges。可以吗?

ChangeDetectorRef.detectChangesNgZone.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按钮将其删除。

0 投票
1 回答
347 浏览

angular - API调用后Angular组件不更新

我有一个下拉组件,它将模型作为[输入]。

在父母我有:

问题是不更新子组件。所以下拉列表不会更新。我可以看到 viewModel 已初始化。

我已经用一种方式绑定了它 [ this.viewModel.dropdownItems ]

我也在其他地方使用这个下拉组件,所以我知道它可以工作。(不知道api调用虽然不知道我是否在其他地方这样做)

0 投票
2 回答
465 浏览

angular - 当 ChildComponent 发生变化时如何监听然后在 ParentComponent 中执行方法?

我正在 Angular 7 中寻找一个干净有效的解决方案,以便在每次子组件更改时执行组件中的方法。

给定一个ParentComponent渲染 a ChildComponent,我需要知道什么时候ChildComponent改变了,然后在ParentComponent.

通过更改,我指的是视图或子类中任何属性的更改。

谢谢。

0 投票
1 回答
795 浏览

angular - 嵌入与 ng-content 子项的不同 ChangeDetectionStrategy.OnPush 行为

我正在调整应用程序的性能并遇到以下差异。请参阅stackblitz以获取实时示例。

带有后缀的组件-on-pushChangeDetectionStrategy.OnPush,而带有后缀的组件-default有默认策略。

我有两种方法,我将第一种方法命名为“嵌入式”,将第二种方法命名为“ng-content”。澄清如下。

根模板:

其中app-embedded-on-pushs 模板只是“嵌入”了app-embedded-default组件:

另一方面,app-ng-content-on-pushs 模板将app-ng-content-default组件投影为ng-content

请查看 stackblitz 以获得更好的想法。

期待

由于ChangeDetectionStrategy.OnPush只有在输入引用发生更改时才检查组件(组件本身及其子级),我的期望是在组件本身及其子级上,更改检测不会被两种方法触发,命名为嵌入和内容投影方法。

现实

使用嵌入式方法,行为符合预期,app-embedded-default不会触发更改检测。另一方面,通过内容ng-content投影(app-ng-content-on-push

有人可以解释为什么这是结果行为吗?两种方法的组件树都是相同的,还是我错了?

0 投票
1 回答
62 浏览

angular - ngOnInit 上的 Angular 将 false 更改为 true

我有一项服务,其中包含一组选定的 ID。当我初始化一个组件时,我会检查该组件的 ID 在数组中是否存在。但是,Angular 会抛出一个异常,即视图检查后值已更改。

我试过在detectChanges()之后添加this._checked = true,试过了markForCheck()。此外,我尝试将这两种情况移动到不同的生命周期挂钩,但没有成功,只是它开始工作,尽管抛出错误。

0 投票
1 回答
4651 浏览

angular - 使用模板内的 getter 触发的角度变化检测循环

似乎在模板中使用 getter 会导致 Angular 更改检测进入循环(getter 被调用数百次)。在阅读了大量关于类似问题的文章后,我似乎无法得到明确的答案。

背景资料:

从可维护性的角度来看,我确实相信在模板中使用 getter 是最干净的方法,但似乎因为 Angular 在调用它之前无法知道 getter 值是否发生了变化,它只是一直调用它。到目前为止,我找到了三种选择:

  1. 停止使用 getter,公开所有属性并直接访问它们
  2. 将每个 getter 的值存储到组件上的公共属性中并绑定它而不是模板中的 getter
  3. 将 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没有找到解决方案(似乎天生不兼容),如果我找到解决方案,将更新。

0 投票
1 回答
111 浏览

angular - public get 从 auth 服务返回一个权限布尔值,初始化为 false 并在 NGRX 存储返回值但未定义时修改

我有一个 Angular7 应用程序,我选择在 app.component 中显示一个基于布尔值的按钮,该布尔值定义为:

现在在我的身份验证服务中,我在权限模型之后初始化了 userPermissions,所有权限都标记为“false”。

在 Authentication 上,权限数组被发送到 reducer,并且正在使用 ngrx 存储设置权限。

在服务中,我订阅了该存储值并更新了权限对象。

现在的问题是,身份验证后第一次整个事情崩溃返回:

引用我定义 getter 的行。

但它在任何地方都有定义。我的代码中没有一个地方我没有初始化并使用“false”默认值定义模型变量。

在我处理权限数组的减速器中:

似乎我忘记使用该数组中的权限更新模型,当 for 循环到达时,它使整个状态未定义。

0 投票
1 回答
523 浏览

angular - 如何在 Angular 7 中使用 ChangeDetection(视图未更新)?

我不知道如何在我的 Angular 应用程序中使用 Change-Detection。我的方法的目标是,仅当我的表列表中的数据发生更改时才显示更新列表。

目前,当我更改表格列表中的一行时,仅显示第一个数据。在控制台中,我看到了第二个更改的数据,但我的视图没有更改更新列表。

这是我的组件:

和我的观点:

谁能帮我解决这个问题?

0 投票
0 回答
149 浏览

angular - ngIf 指令如何改变检测更改周期?

Stackblitz 示例:https ://stackblitz.com/edit/ngif-detectionchange

testToggle由于绑定到其中的某些属性,我有可以更改其高度的组件。它有兄弟testParent组件,它是 flex 以获取其余高度,并且它testChild具有绑定到testParent高度的子组件。当testParent*ngIf 指令具有真表达式时,当testToggle更改绑定到其高度的属性时,我得到:

错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。

在记录组件的生命周期钩子顺序后,我发现了一些奇怪的东西:

显然,正确的示例抛出 ExpressionChanged,因为整个testParent周期已经结束,之前testToggle可以更新它的绑定(这会改变它的高度,因此改变testParent高度)。

我想知道为什么使用 ngIf 动态添加的组件在通过组件树正常继续之前完成其整个生命周期?