首页 文章

使用* ngIf模板变量loadIntoLocation以编程方式将组件加载到视图中

提问于
浏览
3

我正在尝试构建一个登录页面,其中登录模板被app router-outlet替换 .

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>

组件

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");
}
}

我试图:1)显示登录模板2)登录成功更新logedin 3)相应地隐藏登录4)显示应用程序

这会导致错误消息:

Could not find variable header

我理解这种情况正在发生,因为#header是* ngIf模板范围内的局部变量 . 我尝试用几种方法解决这个技术(使用* ngIf和局部变量#而不是使用loadIntoLocation交换模板)但没有成功 .

事情是我的应用程序框架(意思是导航 Headers )没有通过<router-outlet>加载所以我需要一个条件方式来加载框架组件而不使用路由(因为<router-outlet>只在我的情况下呈现内容),登录成功后返回 .

帮助会很有帮助 .

2 回答

  • 3

    当模板变量在 *ngIf 内时,找不到它 . 我不知道这是设计还是错误 . 这是设计的 .

    update Angular 2 dynamic tabs with user-click chosen components显示了具有最新代码的相同示例 .

    original (outdated code)

    如果你需要使用 DynamicComponentLoader ,你可以使用像这样的包装器组件

    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.17
    Plunker example <= beta.15

  • 0

    我使用Michael D建议使用[hidden] html5属性解决了这个问题 . 我不知道隐藏的html5 attr .

    更改了html:

    <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>
    

    至:

    <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>
    

相关问题