Angular 4 - 如何根据组件中的条件加载html文件

时间:2017-12-11 09:40:01

标签: angular

我想根据条件加载HTML文件。如果我的浏览器宽度小于1000px,我需要加载HTML,否则需要加载其他HTML文件。

我试过

import {
    Component,
    HostListener
} from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: `{{tmplUrl}}`,
    styleUrls: ['./app.component.css']
})
export class AppComponent {

    tmplUrl: string = './app.component.html';

    @HostListener('window:resize', ['$event'])
    onResize(event) {
        if (event.target.innerWidth <= 1000) {
            this.tmplUrl = "./app_mobile.component.html";
        } else {
            this.tmplUrl = "./app.component.html";
        }
    }
}

以上代码无效。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

考虑在Angular中使用动态组件加载器。

创建两个具有要动态加载的模板的组件,让我们称之为MobileComponent和OtherComponent。它们都将实现一个ParentComponent,它只是一个接口。这是他们的代码:

父组件

export interface ParentComponent {
  someName: string;
}

MobileComponent

import { Component } from '@angular/core';
import {ParentComponent} from './parent.component';

@Component({
  template: `
      <h4>Mobile Template</h4> 
  `
})
export class MobileComponent implements ParentComponent {
  someName = 'mobile';
}

OtherComponent

import { Component } from '@angular/core';
import {ParentComponent} from './parent.component';

@Component({
  template: `
      <h4>Other Template</h4>
  `
})
export class OtherComponent implements ParentComponent {
  someName = 'other';
}

然后创建一个提供这些组件的服务。我们称之为ComponentService。这是它的代码

import { Injectable }           from '@angular/core';

import { MobileComponent }   from './mobile.component';
import { OtherComponent }   from './other.component';

@Injectable()
export class ComponentService {
  getComponents() {
    return {
      'mobile': {
        component: MobileComponent
      },
      'other': {
        component: OtherComponent
      }
    }
  }
}

创建一个锚指令,这里是它的代码:

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[anchor-host]',
})
export class AnchorDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

现在创建RootComponent,它将动态加载MobileComponent和OtherComponent。这是RootComponent的代码:

import {Component, HostListener, AfterViewInit, OnDestroy, Input, ViewChild} from '@angular/core'
import {AnchorDirective} from './anchor.directive'
import { ComponentFactoryResolver } from '@angular/core';
import {ParentComponent} from './parent.component'

@Component({
  selector: 'my-root',
  template: `
    <div>
      <h2>in root</h2>

      <ng-template anchor-host>
      </ng-template>

    </div>
  `,
})
export class Root implements AfterViewInit, OnDestroy {

  private currentTemplate: string = 'other'; 

  @Input() components: Array<any>;

  @ViewChild(AnchorDirective) anchorHost: AnchorDirective;

  constructor(private componentFactoryResolver: ComponentFactoryResolver) {}

  @HostListener('window:resize', ['$event'])
    onResize(event) {
        if (event.target.innerWidth <= 500) {
           console.log('res1');
           this.currentTemplate = 'mobile';
        } else {
          console.log('res2');
          this.currentTemplate = 'other';
        }
        this.loadComponent();
    }

  ngAfterViewInit() {
    this.loadComponent();
  }

  loadComponent() {
    let component = this.components[this.currentTemplate].component;

    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);

    let viewContainerRef = this.anchorHost.viewContainerRef;
    viewContainerRef.clear();

    let componentRef = viewContainerRef.createComponent(componentFactory);
  }

}

现在让你的AppComponent看起来如下:

@Component({
  selector: 'my-app',
  template: `
      <my-root [components]="componentArr"></my-root>
  `,
})
export class App implements OnInit {
  componentArr = []
  constructor(private components: ComponentService) {}

  ngOnInit() {
    this.componentArr = this.components.getComponents();
  }
}

让你的app模块如下所示:

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, Root, AnchorDirective, MobileComponent, OtherComponent ],
  providers: [ComponentService],
  entryComponents: [ MobileComponent, OtherComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

以下是你想要的东西:

https://plnkr.co/edit/zff8j5AkHjzJDdwffa70?p=preview

尝试调整窗口大小以查看其工作原理,并根据您的需要更改其模板。

您可以通过以下链接查看有关它的更多信息并找出其工作原理(+如果您想将一些数据注入到组件中作为输入,您也可以在此页面中找到此示例): https://angular.io/guide/dynamic-component-loader