I have a parent component that uses ng2-toastr (4.1.2).
Parent element :
import { Component, ViewContainerRef } from '@angular/core';
import { AfterViewInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
declare var jquery: any;
declare var $: any;
import { ToastsManager } from 'ng2-toastr/ng2-toastr';
import { File } from '../models/file';
import { Tag } from '../models/tag';
import { Group } from '../models/group';
import { CmsService } from '../services/cms.service';
@Component({
selector: 'app-cms',
template: `
<ul *ngFor="let directory of structure?.root.directories">
<app-directory (refresh)="refresh($event)" [directory]="directory" *ngIf="directory"></app-directory>
<li *ngFor="let file of directory.files">
{{file.name}}.{{file.extension}}
</li>
</ul>
`,
providers: [
CmsService
]
})
export class CmsComponent {
structure: any;
tags: Array<Tag>;
groups: Array<Group>;
file: {name: string, firstPageAsCover: boolean, shareable: boolean, tags: Array<{id: number}>};
directory: {name: string, requiredGroups: Array<{id: number}>};
constructor (
private cmsService: CmsService,
private toastr: ToastsManager,
private _vcr: ViewContainerRef,
private router: Router
) {
this.toastr.setRootViewContainerRef(_vcr);
}
}
Child element
import { Component, Input, Output, ViewContainerRef, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
declare var jquery: any;
declare var $: any;
import { ToastsManager } from 'ng2-toastr/ng2-toastr';
import { File } from '../models/file';
import { Directory } from '../models/directory';
import { CmsService } from '../services/cms.service';
@Component({
selector: 'app-directory',
template: `
<li class="directory" data-id="{{directory.id}}">
<a (click)="toggle($event.target, directory.id)">+</a>
{{directory.name}}
<a class="action addFolder" (click)="addDirectory(directory)"></a>
<a class="action editFile" (click)="editDirectory(directory)"></a>
<a class="action addFile" (click)="add(directory)"></a>
<ul class="sub d-none">
<app-directory *ngFor="let dir of directory.directories" (refresh)="refreshChild($event)" [directory]="dir"></app-directory>
<li class="file" *ngFor="let file of directory.files">
<a (click)="displayFile(file.id)">
{{file.name}}.{{file.extension}} | {{file.sizeInBytes / 1024}} kb | {{file.lastModified}} | {{file.timesViewed}}
</a>
<a class="action editFile" (click)="edit(file)"></a>
<a class="action link" (click)="link(file.id)"></a>
<a class="action download" (click)="download(file.id)"></a>
<a class="action delete" (click)="delete(file.id)"></a>
</li>
</ul>
</li>
`,
providers: [
CmsService
]
})
export class DirectoryComponent {
@Output() refresh: EventEmitter<any> = new EventEmitter();
@Input() directory: Directory;
constructor (
private cmsService: CmsService,
private toastr: ToastsManager,
private _vcr: ViewContainerRef,
private router: Router
) {
this.toastr.setRootViewContainerRef(_vcr);
}
ngOnInit() {
this.toastr.success('cucu', 'cucu');
}
}
When I try to enable the toastr in the child element, it only works first time it's loaded. Then I have this message :
ERROR Error: Uncaught (in promise): Error: ViewDestroyedError: Attempt to use > a destroyed view: detectChanges
Also, the toastr doesn't work anymore on the parent element.
Please note that the child element is recursive.
Thanks !
You need to set setRootViewContainerRef only on root element.
So remove
this.toastr.setRootViewContainerRef(_vcr);
on child component and you will be fine.