Toastr 传递给 angular4 中的子元素
Toastr passed to child element in angular4
我有一个使用 ng2-toastr (4.1.2) 的父组件。
父元素:
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);
}
}
子元素
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');
}
}
当我尝试在子元素中启用 toastr 时,它仅在第一次加载时起作用。
然后我收到这条消息:
ERROR Error: Uncaught (in promise): Error: ViewDestroyedError: Attempt to use > a destroyed view: detectChanges
此外,toastr 在父元素上不再起作用。
请注意子元素是递归的。
谢谢!
您只需在根元素上设置 setRootViewContainerRef。
所以删除子组件上的 this.toastr.setRootViewContainerRef(_vcr);
就没问题了。
我有一个使用 ng2-toastr (4.1.2) 的父组件。
父元素:
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);
}
}
子元素
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');
}
}
当我尝试在子元素中启用 toastr 时,它仅在第一次加载时起作用。 然后我收到这条消息:
ERROR Error: Uncaught (in promise): Error: ViewDestroyedError: Attempt to use > a destroyed view: detectChanges
此外,toastr 在父元素上不再起作用。
请注意子元素是递归的。
谢谢!
您只需在根元素上设置 setRootViewContainerRef。
所以删除子组件上的 this.toastr.setRootViewContainerRef(_vcr);
就没问题了。