3

Ich versuche eine Login-Seite zu erstellen, auf der die Login-Vorlage durch die App + Router-Outlet ersetzt wird.Verwenden von * ngIf + Template-Variablen + loadIntoLocation zum programmgesteuerten Laden von Komponenten

Die HTML:

<div class="contentWrapper" *ngIf="!logedin"> 
    Login html.... 
</div> 

<div *ngIf="logedin"> 
    <div #header></div> 
    <div class="contentWrapper"> 
     <div #nav></div> 
     <div class="main"> 
      <router-outlet> 
      </router-outlet> 
     </div> 
    </div> 
</div> 

Die Komponente

export class AppComponent implements OnInit{ 
logedin = 0; 

constructor(
    private _dcl:DynamicComponentLoader, 
    private _elmRef:ElementRef, 
    private _httpRest:HttpRest //http calls service 
){} 

ngOnInit(){} 
login(){ 
    var vm = this; 

    //simulated XHR 
    setTimeout(()=>{ 
     vm.postLoginSuccess() 
    }) 
} 
postLoginSuccess(){ 
    var vm = this; 
    vm.logedin = 1; 
    setTimeout(()=>{ 
     vm.loadApp() 
    },0); 
} 
loadApp(){ 
    this._dcl.loadIntoLocation(Header,this._elmRef,"header"); 
    this._dcl.loadIntoLocation(Navigation,this._elmRef,"nav"); 
} 
} 

Ich versuche zu: 1) zeigen eine Login-Vorlage 2) Login Erfolg Update logedin 3) Login ausblenden 4) App anzeigen

Dies führt zu einer Fehlermeldung:

Could not find variable header 

Ich verstehe dies geschieht, weil die #header eine lokale Variable unter dem Umfang der * ngIf Vorlage ist. Ich habe versucht, diese Technik (das Tauschen von Vorlagen mit * ngIf und lokalen Variablen # anstatt mit loadIntoLocation) auf verschiedene Arten ohne Erfolg zu lösen.

Die Sache ist meine App Frame (dh Navigation + Header) wird nicht über die < Router-Outlet geladen> so brauche ich eine bedingte Möglichkeit zum Laden der Frame-Komponenten ohne Routing zu verwenden (seit < Router-Ausgang> nur Inhalte rendert in meinem Fall), nach dem Login erfolgreich zurückgegeben.

Hilfe wird sehr geschätzt werden.

+1

Hinweis: Sie müssen nicht die var vm brauchen = dies, wenn Sie den Pfeil-Funktionen verwenden. – Dinistro

+1

Können Sie bestätigen, dass Sie [hidden] anstelle von ngIf verwenden, um Ihr Problem zu lösen? –

+0

Ich verstehe nicht, warum Sie etwas mit dem 'DynamicComponentLoader' machen. Warum erstellen Sie nicht eine 'Header'- und eine' Navigation'-Komponente und binden Sie diese in die Vorlage ein. – Dinistro

Antwort

3

Wenn die Template-Variable in einem *ngIf ist, wird es nicht gefunden. Ich weiß nicht, ob das ein Design oder ein Fehler ist. Dies ist mit Absicht.

Update Angular 2 dynamic tabs with user-click chosen components zeigt das gleiche Beispiel mit up-to-date-Code.

Original (veraltete Code)

Wenn Sie DynamicComponentLoader verwenden möchten, können Sie tun, um eine Wrapper-Komponente wie

import {Component, DynamicComponentLoader, ElementRef, Input, ViewChild, ViewContainerRef} from 'angular2/core'; 
@Component({ 
    selector: 'dcl-wrapper', 
    template: `<div #target></div>` 
}) 
export class DclWrapper { 
    @ViewChild('target', {read: ViewContainerRef}) target; 

    constructor(private dcl:DynamicComponentLoader) {} 
    @Input() type; 

    ngOnChanges() { 
    if(this.cmpRef) { 
     this.cmpRef.dispose(); 
    } 
    if(this.type) { 
     this.dcl.loadNextToLocation(this.type, this.target).then((cmpRef) => { 
     this.cmpRef = cmpRef; 
     }); 
    } 
    } 
} 
@Component({ 
    selector: 'header-comp', 
    template: 'header' 
}) 
export class Header{} 

@Component({ 
    selector: 'my-app', 
    directives: [DclWrapper], 
    template: ` 
    <h1>Hello</h1> 
<div class="contentWrapper" *ngIf="!logedin"> 
    Login html.... 
</div> 

<div *ngIf="logedin"> 
    <dcl-wrapper [type]="headerCmp"></dcl-wrapper> 
    <div class="contentWrapper"> 
     <div #nav></div> 
     <div class="main"> 
      <router-outlet> 
      </router-outlet> 
     </div> 
    </div> 
</div> 

<button (click)="login()">log in</button> 
    `, 
}) 
export class AppComponent { 
    constructor(
    private _dcl:DynamicComponentLoader, 
    private _elmRef:ElementRef, 
    /*private _httpRest:HttpRest*/ /*http calls service*/){} 

    headerCmp = null; 
    logedin = true; 
    ngOnInit(){} 

    login(e){ 
    console.log('login'); 
    //var vm = this; 

    //simulated XHR 
    setTimeout(()=>{ 
     this.postLoginSuccess() 
    }) 
    } 

    postLoginSuccess(){ 
    //var vm = this; 
    this.logedin = true; 
    setTimeout(()=>{ 
     this.loadApp(); 
    }); 
    } 

    loadApp(){ 
    console.log('loadApp'); 
    this.headerCmp = Header; 
    //this._dcl.loadIntoLocation(Header,this._elmRef,"header"); 
    //this._dcl.loadIntoLocation(Navigation,this._elmRef,"nav"); 
    } 
} 

Plunker example beta.17mit 0 Plunker example <= beta.15

0

Ich löste dieses Problem mit Michael D Beratung, das Attribut [hidden] html5 zu verwenden. Ich war mir der versteckten html5 attr nicht bewusst.

Changed html aus:

<div class="contentWrapper" *ngIf="!logedin"> 
</div> 
<div *ngIf="logedin"> 
<div #header></div> 
<div class="contentWrapper"> 
    <div #nav></div> 
    <div class="main"> 
     <router-outlet> 
     </router-outlet> 
    </div> 
</div> 

An:

<div class="contentWrapper" [hidden]="logedin"></div> 
<div [hidden]="!logedin"> 
<div #header></div> 
<div class="contentWrapper"> 
    <div #nav></div> 
    <div class="main"> 
     <router-outlet> 
     </router-outlet> 
    </div> 
</div> 

Verwandte Themen