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); 就没问题了。