我有以下创建MdDialog
的组件export class SideNavsComponent implements OnInit, AfterViewInit, OnDestroy {
eventDispatcher: EventDispatcher
authEmailDialogRef: MdDialogRef<AuthEmailDialogComponent>
constructor(public dialog: MdDialog,) {
this.eventDispatcher = new EventDispatcher()
}
signIn( event ): void {
this.isSignedIn = event.checked
this.openDialog()
}
openDialog() {
this.authEmailDialogRef = this.dialog.open( AuthEmailDialogComponent, {
height: '500px',
width: '300px',
disableClose: true
} )
}
ngOnDestroy() {
}
ngAfterViewInit() {
}
ngOnInit() {
event_dispatcher.on( 'CLOSE authEmailDialogRef', ( target: Object ) => {
this.authEmailDialogRef.close()
} )
}
}
下面的组件创建了一个按钮,单击该按钮时,通过发送和在SideNavsComponent#ngOnInit方法中拦截的事件来关闭上面创建的MdDialog
export class AuthEmailDialogComponent implements OnInit {
eventDispatcher: EventDispatcher = new EventDispatcher()
}
cancel() {
event_dispatcher.dispatch( 'CLOSE authEmailDialogRef', '')
}
}
MdDialog已关闭(),但检测更改错误始终发生在以下情况:
ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges
at viewDestroyedError (core.es5.js:8636)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:12781)
at checkAndUpdateView (core.es5.js:12122)
at callWithDebugContext (core.es5.js:13184)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.es5.js:12724)
at ViewRef_.detectChanges (core.es5.js:10196)
at asterisk.component.ts:37
at ZoneDelegate.webpackJsonp.1467.ZoneDelegate.invokeTask (zone.js:414)
at Object.onInvokeTask (core.es5.js:4119)
at ZoneDelegate.webpackJsonp.1467.ZoneDelegate.invokeTask (zone.js:413)
View_MdDialogContainer_Host_0 @ MdDialogContainer_Host.html:1
proxyClass @ compiler.es5.js:14091
DebugContext_.logError @ core.es5.js:13124
ErrorHandler.handleError @ core.es5.js:1144
next @ core.es5.js:4757
schedulerFn @ core.es5.js:3830
SafeSubscriber.__tryOrUnsub @ Subscriber.js:236
SafeSubscriber.next @ Subscriber.js:185
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3816
NgZone.triggerError @ core.es5.js:4188
onHandleError @ core.es5.js:4149
webpackJsonp.1467.ZoneDelegate.handleError @ zone.js:385
webpackJsonp.1467.Zone.runTask @ zone.js:184
ZoneTask.invoke @ zone.js:476
timer @ zone.js:1491
setInterval (async)
scheduleTask @ zone.js:1501
webpackJsonp.1467.ZoneDelegate.scheduleTask @ zone.js:400
onScheduleTask @ zone.js:290
webpackJsonp.1467.ZoneDelegate.scheduleTask @ zone.js:394
webpackJsonp.1467.Zone.scheduleTask @ zone.js:225
webpackJsonp.1467.Zone.scheduleMacroTask @ zone.js:248
(anonymous) @ zone.js:1527
proto.(anonymous function) @ zone.js:1402
AsteriskComponent @ asterisk.component.ts:37
createClass @ core.es5.js:10870
createDirectiveInstance @ core.es5.js:10701
createViewNodes @ core.es5.js:12064
callViewAction @ core.es5.js:12508
execComponentViewsAction @ core.es5.js:12417
createViewNodes @ core.es5.js:12091
createRootView @ core.es5.js:11969
callWithDebugContext @ core.es5.js:13184
debugCreateRootView @ core.es5.js:12644
ComponentFactory_.create @ core.es5.js:9890
ComponentFactoryBoundToModule.create @ core.es5.js:3427
ViewContainerRef_.createComponent @ core.es5.js:10092
PortalHostDirective.attachComponentPortal @ material.es5.js:2135
MdDialogContainer.attachComponentPortal @ material.es5.js:19218
MdDialog._attachDialogContent @ material.es5.js:19486
MdDialog.open @ material.es5.js:19400
webpackJsonp.751.SideNavsComponent.openDialog @ side-navs.component.ts:39
webpackJsonp.751.SideNavsComponent.signIn @ side-navs.component.ts:35
(anonymous) @ SideNavsComponent.html:32
handleEvent @ core.es5.js:11892
callWithDebugContext @ core.es5.js:13184
debugHandleEvent @ core.es5.js:12772
dispatchEvent @ core.es5.js:8792
(anonymous) @ core.es5.js:10720
schedulerFn @ core.es5.js:3842
SafeSubscriber.__tryOrUnsub @ Subscriber.js:236
SafeSubscriber.next @ Subscriber.js:185
Subscriber._next @ Subscriber.js:125
Subscriber.next @ Subscriber.js:89
Subject.next @ Subject.js:55
EventEmitter.emit @ core.es5.js:3816
ToggleButton.toggle @ togglebutton.js:42
(anonymous) @ ToggleButton.html:4
handleEvent @ core.es5.js:11892
callWithDebugContext @ core.es5.js:13184
debugHandleEvent @ core.es5.js:12772
dispatchEvent @ core.es5.js:8792
(anonymous) @ core.es5.js:9384
(anonymous) @ platform-browser.es5.js:2683
webpackJsonp.1467.ZoneDelegate.invokeTask @ zone.js:414
onInvokeTask @ core.es5.js:4119
webpackJsonp.1467.ZoneDelegate.invokeTask @ zone.js:413
webpackJsonp.1467.Zone.runTask @ zone.js:181
ZoneTask.invoke @ zone.js:476
MdDialogContainer_Host.html:1 ERROR CONTEXT DebugContext_ {view: {…}, nodeIndex: 0, nodeDef: {…}, elDef: {…}, elView: {…}}
如何在销毁组件后阻止changeDetection触发;换句话说,如何在没有错误的情况下使这段代码正常工作?
注意:尝试了很多关于stackoverflow的建议,但都没有。
由于
答案 0 :(得分:10)
问题是对话框的关闭操作是从视图中删除项目,并且您的EventDispatcher 不是一个角度方法,因此它会在区域上下文之外触发并将其吓坏。 它是这样的:
您可以使用其他方法与对话框进行通信,也可以切换到onPush() for change detection
我建议您改用afterClosed
句柄:
this. authEmailDialogRef.afterClosed().subscribe(result => {
console.log(`Dialog result: ${result}`); // Pizza!
});
我直接从文档中提取了该代码段:HERE
答案 1 :(得分:3)
Padegal Saigiriraj是对的。但是请使用ViewRef_
而不是ViewRef
。简而言之:
setTimeout(() => {
if (this.cdr && !(this.cdr as ViewRef).destroyed) {
this.cdr.detectChanges();
}
});
ViewRef代表Angular视图,尤其是Angular site描述的宿主视图。
答案 2 :(得分:2)
此问题发生的原因是您删除了change事件上的sortableData或dragableData上的引用。 在抽象类中,detectChange方法在触发更改检测之前等待250 ms,这时您的视图和组件将被破坏。
setTimeout(() => {
if (this.cdr !== null && this.cdr !== undefined &&
!(this.cdr as ViewRef_).destroyed) {
this.cdr.detectChanges();
}
}, 250);