- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
有一个组件封装了一些库。为了避免所有该库的事件监听器的变更检测噩梦,该库的范围在 Angular 区域之外:
@Component({ ... })
export class TestComponent {
@Output()
emitter = new EventEmitter<void>();
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
// ...
});
}
}
这一切都非常清楚和普遍。现在让我们添加事件以发出操作:
@Component({ ... })
export class TestComponent {
@Output()
emitter = new EventEmitter<void>();
private lib: Lib;
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.lib = new Lib();
});
this.lib.on('click', () => {
this.emitter.emit();
});
}
}
问题是这个发射器不会触发变化检测,因为它是在区域外触发的。那么有可能重新进入该区域:
@Component({ ... })
export class TestComponent {
@Output()
emitter = new EventEmitter<void>();
private lib: Lib;
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.lib = new Lib();
});
this.lib.on('click', () => {
this.ngZone.run(() => this.emitter.emit());
});
}
}
最后,我来谈谈这个问题。此 this.ngZone.run
会强制执行更改检测,即使我没有在父组件中监听此事件也是如此:
<test-component></test-component>
这是不需要的,因为我没有订阅那个事件 => 没有什么可检测的。
该问题的解决方案是什么?
对于那些对现实生活中的例子感兴趣的人,问题的来源是here .
最佳答案
请记住,根据定义,发出值的 @Output()
绑定(bind)是父级更改检测的触发器。虽然该绑定(bind)可能没有任何监听器,但在引用该组件的父模板中可能存在逻辑。也许通过 exportAs
或 @ViewChild
查询。因此,如果您发出一个值,您就是在通知父级组件的状态已更改。也许将来 Angular 团队会改变这一点,但这就是目前的工作方式。
如果你想绕过那个 observable 的变化检测,那么不要使用 @Output
装饰器。移除装饰器并通过 exportAs
访问 emtter
属性或在父组件中使用 @ViewChild
。
了解响应式表单的工作原理。控件指令具有针对不使用 @Output
的更改的公共(public)可观察对象。它们只是公共(public)可观察对象,您可以订阅它们。
因此,如果您想要一个不与变更检测耦合的可观察对象,则只需将其设为公开的可观察对象即可。这只是保持简单。添加逻辑以仅在 @Output
有订阅者时才发出,这会使您稍后阅读源代码时难以理解码件。
话虽如此,这就是我将如何回答您的问题,以便您可以仅在有订阅者时使用 @Output()
。
@Component({})
export class TestComponent implements OnInit {
private lib: Lib;
constructor(private ngZone: NgZone) {
}
@Output()
public get emitter(): Observable<void> {
return new Observable((subscriber) => {
this.initLib();
this.lib.on('click', () => {
this.ngZone.run(() => {
subscriber.next();
});
});
});
}
ngOnInit() {
this.initLib();
}
private initLib() {
if (!this.lib) {
this.ngZone.runOutsideAngular(() => {
this.lib = new Lib();
});
}
}
}
如果我以后看到这段源码,我会有点疑惑程序员为什么要这么做。它添加了很多额外的逻辑,这些逻辑并不能清楚地解释逻辑正在解决的问题。
关于angular - 最佳从 EventEmitter 事件重新进入 ngZone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51787972/
我的 NgZone 似乎不再工作了。我正在使用 Ionic、Angular 和 Firebase 构建应用。 它产生一个错误: Unhandled Promise rejection: Missing
更新堆栈跟踪中的任何更改始终会返回到 globalZoneAwareCallback .你如何找出是什么触发了变化? 在调试方面最好有一个清晰的画面。 最佳答案 globalZoneAwareCall
我的 angular 项目中有一个错误,最终通过将我的代码包装到 this.zone.run(() => {/* my code here */}); 如 this 所述回答。 我之前的理解zone是
我有一个 Angular2 组件,它有一个自定义的第 3 方 JQuery 插件(我们必须使用且无法更改),该插件在 OnInit 事件中初始化。但是,这个第 3 方库充分使用了 setInterva
我正在使用 Angular 2。 有没有办法检查代码现在是否在 NgZone 中? 是这样的吗? constructor(ngZone: NgZone) {} foo() { co
我有一个使用 Angular Google map 显示位置的应用程序。一开始我能够显示 map ,但一段时间后(可能我已经修改了一些东西)我收到以下错误: ERROR Error: Uncaught
我今天在我的代码库中看到了以下内容,并试图理解它可能会做什么: public ngOnInit(): void { this.siteTitle = this.modalService.sit
我在实现 NgZones 时遇到了问题。即使我已经定义了 NgZone,我也会收到这个错误。 “NodeInvocationException:由于错误而导致预呈现失败:ReferenceError:
我正在尝试使用 ngZone 在区域稳定后更新我的分页状态,以便我尝试分页的组件将被完全渲染,并且我将从渲染器获得正确的 scrollWidth。 它在 Angular Material 2 中的使用
有一个组件封装了一些库。为了避免所有该库的事件监听器的变更检测噩梦,该库的范围在 Angular 区域之外: @Component({ ... }) export class TestComponen
我正在使用 Geocoder API,当返回结果时,双向数据绑定(bind)不起作用。数据只是不在 View 内刷新。如果我手动更改任何其他属性,数据就会刷新...因此,我在谷歌上搜索(很多)并找到了
我最近将我公司的网站从 React 移到了 Angular,因为我们的大多数项目已经在 Angular 7 上。作为“使用最新和最伟大”的人,我决定实现服务器端渲染使谷歌页面速度评级接近 100/10
我正在尝试优化 angular 应用程序中代码的性能。 我知道我可以runOutsideAngular一些代码,以免在每个代码运行或事件上引起更改检测。 但是,我是否需要使用 runOutsideAn
我正在延迟用户输入以匹配用户键入,当我使用 ngZone 服务时,它给我这样的错误 core.es5.js:1084 ERROR TypeError: Cannot read property 'ru
之前成功使用过Angular的提前编译。现在我已经在我的应用程序中添加了路由和延迟加载,但我无法再让它工作了。 我已经更新我的代码以使用 2.0(最新)版本,并且当我即时编译时它运行良好。但是在提前编
我将如何继续为以下组件运行 jasmine 测试: @Component({ moduleId: module.id, selector: "testComp", template: "{
在 Chrome DevTools 中仍然收到警告是否正常 [Violation] 'setTimeout' handler took 103ms zone.js:1894 即使您在 ngzone 之
总结 我创建了一个 Angular 6 库,但当我尝试在创建它的项目之外使用它时出现错误。这看起来像很多代码,但它主要是由 CLI 生成的样板。 最小工作测试用例 我使用 Angular 6 CLI
是否可以访问 angular(2+) ZoneJS 实例 (NgZone) 无需 注入(inject)它在 constructor 中像这样: ... const zone = window['']
我正在尝试在一个小项目中使用 NgZone,但不知道如何引入它。angular.io 上的文档说它们适用于 javascript,但似乎使用的是 typescript。 Angular2 docs o
我是一名优秀的程序员,十分优秀!