javascript - 使用 *ngIf + 模板变量 + loadIntoLocation 以编程方式将组件加载到 View 中

标签 javascript typescript angular angular2-routing angular2-template

我正在尝试构建一个登录页面,其中登录模板已替换为 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)登录成功更新登录 3)相应地隐藏登录 4) 显示应用

这会导致错误消息:

Could not find variable header

我知道这是因为 #header 是 *ngIf 模板范围内的局部变量。我尝试以多种方式解决此技术(使用 *ngIf 和局部变量交换模板 # 而不是使用 loadIntoLocation),但没有成功。

问题是我的应用程序框架(意思是导航 + 标题)不是通过 加载的,所以我需要一种有条件的方法来加载框架组件而不使用路由(因为 只呈现内容我的情况),登录成功返回后。

我们将不胜感激。

最佳答案

当模板变量在 *ngIf 中时,找不到它。 我不知道这是设计使然还是错误。这是设计使然。

更新 Angular 2 dynamic tabs with user-click chosen components显示带有最新代码的相同示例。

原始(过时的代码)

如果您需要使用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

关于javascript - 使用 *ngIf + 模板变量 + loadIntoLocation 以编程方式将组件加载到 View 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36713009/

相关文章:

css - 如何替换 Angular 组件的css类

angular - PrimeNG 菜单项命令绑定(bind)到基类函数

查询参数更改时,Angular 路由器导航不会加载页面

javascript - 在api上提交表单的post方法

typescript - Vue 2.5 vue-class-component 使用 Vue 命名空间,但它是一个类型

javascript - 实现任意对象的通用、轻量级且不显眼的标记?

javascript - document.dispatchEvent() 在 Firefox 中不起作用

javascript - 在 TypeScript 和 AngularJS 2 中导入 JavaScript 函数

javascript - ng-repeat 数组

javascript - 当 children 聚焦时防止浏览器移动元素