2016-04-05 9 views
2

Mein CoreComponent meine NotificationsService erzählt eine neue Meldung zu zeigen und übergibt eine HTML-Zeichenfolge in der content Immobilie finden:kann nicht variabel nach innen * ngFor in Angular 2

export class CoreComponent { 

    constructor(private _notificationsService: NotificationsService) { 
    this._notificationsService.show({content: '<h1 (click)="close()">hej hej</h1>'}); 
    } 
} 

Dann ist mein NotificationsComponent ins Spiel kommt, nachdem die NotificationsService haben die Mitteilung an die Komponente weitergeleitet, muss diese Komponente eine gefälschte Komponente machen, so dass alle Bindungen und auf der hTML-in content gesetzt Richtlinien arbeiten:

export class NotificationsComponent { 
    public notifications: string[] = []; 

    constructor(private _notificationsService: NotificationsService, dcl: DynamicComponentLoader, elementRef: ElementRef, injector: Injector) { 

    _notificationsService.newNotification$.subscribe(
     notification => { 

     this.notifications.push(notification); 

     if (notification.content) { 

      dcl.loadIntoLocation(toComponent(notification.content, []), elementRef, 'content'); 

      function toComponent(template, directives = []) { 

      @Component({ 
       selector: 'custom-content', 
       template: template, 
       directives: directives 
      }) 

      class FakeComponent {} 

      return FakeComponent; 
      } 
     } 
     } 
    ) 
    } 
} 

Dann macht er eine Benachrichtigung mit einer *ngFor Schleife:

<div> 
    <ul> 
    <li *ngFor="#notification of notifications"> 
     <div #content></div> 
    </li> 
    </ul> 
</div> 

Das Problem ist aber, dass es nicht die #content Variable aus irgendeinem Grunde nicht finden, es wirft nur ein Uncaught Could not find variable content. Meine Vermutung ist, weil es in einer Schleife ist, aber ich weiß wirklich nicht warum, wenn das der Fall ist.

Wie kann ich diese gefälschte Komponente in die Benachrichtigungsvorlage rendern (vorzugsweise vor dem Push notification in public notifications, so dass die Komponente tatsächlich von Anfang an da ist, wenn eine neue Benachrichtigung angezeigt wird)?

EDIT: Ich fand heraus, dass ohne die *ngFor mein Code funktioniert, aber es gibt etwas über die Schleife, die hier Probleme verursacht. Weiß jemand, warum das passiert?

+0

Ich denke, das Problem ist, dass Sie mehrere Elemente mit dem '# content' Template-Variable zu erzeugen. –

+0

@ GünterZöchbauer Aber wenn das der Fall ist, warum macht es nicht 1 Element und irgendwelche Elemente, die danach hinzugefügt werden, wirft einen Fehler auf? Macht keinen Sinn. – Chrillewoodz

+0

Sie haben Recht, es sollte funktionieren. Siehe auch https://github.com/angular/angular/issues/6920 –

Antwort

2

um die ngFor Problem umgehen Sie ein Wrapper-Element erstellen könnten, dass die tatsächlichen dcl.loadIntoLocation()

Diese Wrapper-Komponente für jede notification zugegeben hat und bekommt die comonent geführt, dass sie in sich selbst dann hinzufügt.

@Component({ 
    selector: 'dcl-wrapper', 
    template: `<div #target></div>` 
}) 
export class DclWrapper { 
    constructor(private containerRef:ViewContainerRef, private dcl:DynamicComponentLoader) {} 
    @Input() component; 

    ngOnChanges() { 
    if(this.cmpRef) { 
     throw 'currently changing type after the component was added is not supported' 
    } 
    this.dcl.loadNextToLocation(this.component, this.containerRef).then((cmpRef) => { 
     this.cmpRef = cmpRef; 
    }); 
    } 
} 
@Component({ 
    selector: 'core-comp', 
    directives: [DclWrapper], 
    template: ` 
    <h2>Tabs</h2> 
    <div *ngFor="let notification of notifications"> 
    <dcl-wrapper [component]="notification"></dcl-wrapper> 
    </div> 
` 
}) 
export class NotificationsComponent { 
    public notifications: string[] = []; 
    ... 
} 

Wie erklärt auch in Angular 2 dynamic tabs with user-click chosen components

+0

Was macht' this.cmpRef = cmpRef' eigentlich? Wie ich weiß, was es tut, aber warum brauche ich es? – Chrillewoodz

+0

Dies ist, um den Verweis auf die erstellte Komponente zu speichern, um es mit 'this.cmpRef.dispose()' entfernen zu können (wenn ich den Methodennamen richtig erinnere). –

+0

Hmm ok. Nun, es löst das Problem, das ich hatte, also werde ich die Antwort akzeptieren. Vielen Dank :) – Chrillewoodz

Verwandte Themen