问题标签 [angular2-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 投票
3 回答
5669 浏览

angular - Angular 2单击事件回调而不触发更改检测

我在尝试(click)在 Angular 2 中的事件回调函数中执行一些逻辑而不触发更改检测时遇到了很大的麻烦。

为什么我不想触发变更检测

回调函数执行简单的动画滚动到顶部。它不会影响其他组件,因此我不需要在每个组件中触发更改检测,事实上我真的不希望它触发!因为更改检测确实会在每个组件中触发,所以动画在移动设备上的性能非常差。

我试过的

我知道我可以使用在区域外运行代码

当您想在区域外运行的代码没有被click, keyup,keydown事件等调用时,这很有效。

因为我的组件看起来像......

<button (click)="doThing()">Do that thing outside the zone!</button>

...myFunction将在区域外运行,但该click事件将触发更改检测。

我已经OnPush在尽可能多的组件中实施了变更检测策略。

此处未触发更改检测很重要,但我找不到阻止它的方法。

编辑 请参阅此plnk ,并将所有组件中的更改检测设置为OnPush。单击子行组件按钮会触发子行、行和应用程序组件中的 CD。

0 投票
1 回答
6845 浏览

angular - 角度 2 订阅值更改未反映在 html 上

这让我很困惑。我可能对订阅的工作原理没有深入的了解。

Angular 2 最终版本

目标:基于角色隐藏/显示导航菜单方法:我使用 Facebook 来验证用户。身份验证后,将检索用户角色并用于确定是否应显示管理菜单。使用 true 进行 observable.next 调用,导航栏组件订阅将拾取标志并将 isAdmin 更改为 true。(开始时 isAdmin 为 false)这将允许显示 Admin 菜单。

问题:订阅者正确选择了 true 标志,并且 isAdmin 设置为 true。但是,管理员菜单不显示。

navbar.component.ts

导航栏.html

app.component.ts

安全服务.ts

这有什么问题吗?或者有更好的方法来实现目标?任何建议将不胜感激!谢谢

更新

根据 peeskillet 提供的答案,我从组件中删除了 changeDetection 行,它可以正常工作。

但是,当我进一步处理代码时,我会移动

到另一个服务(在这种情况下是 Facebook 服务)并从应用程序组件调用该服务。navbar.compoenent.ts 中的订阅确实获取了更改,但没有触发更改检测。我必须手动触发检测才能使其工作。

更新了 navbar.component.ts

更新了 app.component.ts

这是相当有趣的。显然,我需要了解更多关于角度 2 变化检测的信息。如果有人知道好的参考,请与我分享。

谢谢!!

0 投票
1 回答
813 浏览

javascript - Angular2从外部应用程序调用公开的方法并丢失更改绑定

我有一个公开的方法,我接触过window。此方法与 a 对话Component并修改我在模板中查看的变量。但是当我更改值时,*ngIf()不会触发。

应用程序组件

公共服务

布局管理器组件

所以想法是,当视图最初加载时,视图是空白的。然后,当我键入时angular.methods.CallMe(),它会修改view变量,page1然后应该显示组件的 html。如果我控制台renderView函数成功被调用,只是视图不会改变。

----更新 - 仍然无法正常工作-----

0 投票
1 回答
282 浏览

angular - 在表单控件更改时显示验证消息

脚步:

  1. 普朗克
  2. 进入Name输入框
  3. 留空Name_
  4. 转到并Email输入
  5. 作为一种类型,弹出必填字段错误Name
  6. Name我希望在从to移动时弹出此错误Email,而不是在输入后弹出Email

我该怎么做?

0 投票
1 回答
589 浏览

angular - 分离 ChangeDetectorRef 时更新 AsyncPipe

通过查看在中实现更改检测的方式,如果已分离AsyncPipe,似乎this._ref.markForCheck()不会运行(此处ChangeDetectorRef也已确认)。

这样做的动机是完全控制何时发生更改检测(通过Observable专门使用类似 MVVM 模式)。我正在使用一个对性能非常敏感的代码,我可以完全控制输入,但使用ChangeDetectionStrategy.OnPush触发更改检测不仅用于输入更改,还控制事件触发(如点击事件),这会通过重新运行不需要的更改检测来大大降低性能每次点击都扫一扫。

所以我选择ChangeDetectorRef完全分离,但现在AsyncPipe停止工作了。

这是预期的行为AsyncPipe吗?如果是这样,有没有办法解决这个问题?或者,一种ChangeDetectorStrategy.OnPush不触发控制事件火灾的方法?


编辑:
这是一个人为的例子,说明了我的意思:

0 投票
1 回答
1387 浏览

javascript - Angular 2 Change Detection 使用数组和@Inputs 延迟了几秒钟

我知道 Angular 2 中有大量关于变更检测的信息,并且我一直在尽我所能来了解它。我认为我的问题可能与 Array 的可变性属性有关,但我不确定。所以我们有这些来自 Firebase 的“桶”,我将它们推入一个数组,然后将其传递给一个子组件。这一切都奏效了,数组很快就被填充了,但它需要几秒钟才能在页面上呈现。(但是,当我尝试添加一些 setIntervals 和 setTimeouts 时,它的工作速度要快得多,但除非有一个干净的解决方案,否则我宁愿不这样做。)有没有人足够了解幕后发生的事情简单地向我解释并帮助我吗?谢谢!

0 投票
1 回答
2031 浏览

angular - 在角度 2 中使用 ipcRenderer;触发变化检测

我正在渲染器进程中构建一个角度为 2 的电子应用程序。我的主要进程与套接字服务器通信。每当用户连接到此服务器或断开连接时,我希望在视图中显示用户的状态。

为此,我使用电子的 ipc 将消息从主进程发送到渲染器进程,如下所示

在我看来,然后我有一个(简化的)角度分量,像这样

我成功地记录了来自主进程的消息。

问题是 angular 2 不“知道”电子的 ipc,因此不会触发变化检测status。我见过几个人在这个问题上苦苦挣扎,但还没有找到一个“真正的”解决方案。

我尝试通过注入和(参考:手动触发 Angular2 更改检测)来解决它ApplicationRef,但是ChangeDetectorRef提供的方法(分别为, )都没有提供解决方案。ngZonetick()detectChanges()run()

显然,ipc.on当我遇到错误时,“在”内我无法引用我的类的属性/方法/可注射:例如,这个(https://github.com/JGantner/angular2_change_detection_issue/blob/master/browser/security-level-indicator -component.ts)解决方案(我觉得不是很优雅)导致Uncaught TypeError: Cannot read property 'markForCheck' of undefined.

有人可以帮我解决如何在我的情况下进行变更检测吗?


编辑(黑客):

我找到了一种至少获得我需要/想要的功能的方法:

status-bar.component.ts

socket-status.service.ts

虽然这可行,但我觉得必须有一种更优雅的方式来实现这种行为。

最好的情况是直接在 ipc 回调中设置组件的类属性并触发更改检测......到目前为止,我还无法让它工作,所以任何帮助将不胜感激。

(ps另外,我不知道为什么我必须手动触发this.ref.tick(),这不是我记得在angular 2的早期beta版本中触发变化检测时必须做的事情......)

0 投票
1 回答
2060 浏览

angular - Angular2 变更检测误区 - 用 plunker

我正在尝试使用 Angular2 final 完全理解更改检测。

这包括:

  • 处理变更检测策略
  • 将变化检测器与组件连接和分离。

我以为我已经对这些概念有了一个非常清晰的概述,但是为了确保我的假设是正确的,我写了一个小 plunkr 来测试它们。

我对全局正确的一般理解,但在某些情况下,我有点迷茫。


这是plunker:Angular2 Change detection playground

plunker的快速解释:

很简单:

  • 一个父组件,您可以在其中编辑一个属性,该属性将传递给两个子组件:
  • 在更改检测策略设置为 OnPush 的子节点上
  • 在更改检测策略设置为默认值的子项上

parent 属性可以通过以下任一方式传递给子组件:

  • 更改整个属性对象,并创建一个新对象(“更改 obj ”按钮)(触发对 OnPush 子项的更改检测)
  • 更改属性对象内的成员(“更改内容”按钮)(不会触发 OnPush 子项上的更改检测)

对于每个子组件,可以附加或分离 ChangeDetector。(“分离()”“重新连接()”按钮)

OnPush 子有一个可以编辑的附加内部属性,并且可以显式应用更改检测(“detectChanges()”按钮)


以下是我无法解释的行为的场景:

场景1:

  1. 分离 OnPush Children 和 Default Children 的更改检测器(单击两个组件上的“ detach() ”)
  2. 编辑父属性 firstname 和 lastname
  3. 点击“ Change obj ”将修改后的属性传递给孩子

预期行为: 我希望两个孩子都不会被更新,因为他们的变化检测器都是分离的。

当前行为: 默认子级未更新,但 OnPush 子级已更新..为什么? 它不应该,因为它的 CD 已分离...

场景2:

  1. 为 OnPush 组件分离 CD
  2. 编辑其内部值输入并单击更改内部:没有任何反应,因为 CD 已分离,因此未检测到更改...确定
  3. 单击detectChanges():检测到更改并更新视图。到现在为止还挺好。
  4. 再次,编辑内部值输入并单击更改内部:再次,没有任何反应,因为 CD 已分离,因此未检测到更改.. OK
  5. 编辑父属性 firstname 和 lastname。
  6. 点击“ Change obj ”将修改后的属性传递给孩子

预期行为: OnPush 子级根本不应该更新,再次因为它的 CD 已分离...CD 根本不应该在这个组件上发生

当前行为: 值和内部值都被更新,像一张完整的 CD 一样的接缝被应用到这个组件上。

  1. 最后一次,编辑内部值输入并单击更改内部:检测到更改,并更新内部值...

预期行为: 不应更新内部值,因为 CD 仍处于分离状态

当前行为: 检测到内部值变化...为什么?


结论:

根据这些测试,我得出以下结论,这对我来说很奇怪:

  • 具有 OnPush 策略的组件在其输入更改时会“检测到更改” ,即使其更改检测器已分离。
  • 每次输入更改时,具有 OnPush 策略的组件都会重新附加更改检测器...

您如何看待这些结论?

你能以更好的方式解释这种行为吗?

这是一个错误还是期望的行为?

0 投票
1 回答
761 浏览

angular - 如何检测 Angular 2 反应/动态表单的一个元素发生的变化?

我正在尝试检测使用反应式表单构建的一个特定表单元素的变化。

如https://angular.io/docs/ts/latest/cookbook/dynamic-form.html#中所示,我使用*ngFor*ngSwitch指令构建反应式表单。我的表单当前包含输入类型和. 我使用更改事件来捕获文件上传任务,因此我需要检测输入元素中的更改,而不是输入元素。这就是我遇到问题的地方。使用or构建的表单似乎不会触发事件。我创建了一个可用于重现我面临的问题的plunker 。textfilefiletext*ngSwitch*ngIfchange

如果我检测到每个表单元素的变化,表单就可以正常工作。(在 plunker 示例中的 form2)

请参阅下面链接中的 plunker 以重新解决我面临的问题。 https://plnkr.co/edit/1dMfn7gmR3rHq6xcgr2a?p=preview

有谁知道如何解决这个问题?

0 投票
2 回答
5957 浏览

angular - Angular2 使用 ApplicationRef 手动实现变更检测

获取更改检测错误

检查后表达式已更改。以前的值:“真”。当前值:“假”

所以我想手动运行另一轮更改检测。找到有关使用ApplicationRef.tick()但当前出现错误的信息

[默认] C:\development\SolarUI11\src\app\update\update.component.ts:8 中的错误:11 类型参数 '{ 选择器:字符串;风格:任何[];模板:任何;提供者:( typeof ApplicationRef | typeof Date...' 不可分配给“组件”类型的参数。属性“提供者”的类型不兼容。类型“(typeof ApplicationRef | typeof DatePipe)[]”不可分配给类型“ Provider[]'。类型'typeof ApplicationRef | typeof DatePipe'不可分配给类型'Provider'。类型'typeof ApplicationRef'不可分配给类型'Provider'。类型'typeof ApplicationRef'不可分配给类型'FactoryProvide r' .“typeof ApplicationRef”类型中缺少属性“provide”

我想我只是停留在实现它的语法上,自己找不到足够的信息来使用它。

打字稿: