Angular2:将html模板插入(和编译)到viewRef的最简单方法

时间:2016-10-16 02:12:36

标签: angular

假设我有这个组件:

import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, ViewEncapsulation } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ActivatedRoute, Params } from '@angular/router';
import 'rxjs/add/operator/toPromise';

@Component({
  selector: 'jlm-chapitre',
  templateUrl: './chapitre.component.html',
  styleUrls: ['./chapitre.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ChapitreComponent implements OnInit, AfterViewInit {
  @ViewChild('include', { read: ElementRef }) includeDiv: ElementRef;

  constructor( private route : ActivatedRoute, private http: Http ) { }

  ngAfterViewInit() {
    this.route.params.forEach((params: Params) => {
      let id = +params['chapitreId'];
      this.http.get(`/assets/programme/chapitre0${id}.html`)
      .toPromise()
      .then((res: Response) => {
        this.includeDiv.nativeElement.innerHTML = res.text();
      });
    });
  }

  ngOnInit() {}
}

但问题是插入的HTML内容未编译。

我有一些未确定的html模板,所以我无法为每个html模板创建一个组件...如何插入和编译模板?我们在angular1中有$ compile()。我们有DynamicComponentLoader,但它已被弃用......

编辑:看完第一个答案后,看起来我还不够清楚。 我想从服务器加载原始HTML模板,其中包含指令等,我希望在#includeDiv中(或之后)插入模板时评估这些指令。 看起来Renderer可能会完成这项工作,但我不知道如何使用renderer.insertViewAfter()。无论如何,无论如何修复问题都会让我感到非常高兴。

编辑2:我找到了一个简单的方法来做我刚才在另一个问题的回答中说的话:https://stackoverflow.com/a/39773331/3444388

但我仍然在寻找更清洁的东西。

2 个答案:

答案 0 :(得分:0)

我注意到唯一改变的是章节ID。假设从一个章节到下一个章节的HTML具有相同的基本结构和不同的内容,您可以使用通用模板:

<section *ngIf="ready">
    <h2>{{chapter.title}}</h2>
    <div>{{chapter.description}}</div>
</section>
<section *ngIf="!ready">Loading chapter...</section>

然后在组件中,默认情况下会ready=false。在ngOnInit中,获取章节信息。到达后,将其设置为局部变量,并使ready=true显示模板

chapter;
ready = false;
ngOninit() {
    ...
    let id = +params['chapitreId'];
    this.http.get('...').subscribe(
        data => {
            this.chapter = data;
            this.ready = true;
        }
    )
}

更好的是,您可以在组件加载之前使用Resolve guardfetch the data

答案 1 :(得分:0)

我真的不明白为什么要覆盖每个http响应的内容,但如果要显示列表,只需使用ngFor

如果您想在加载之前不显示内容,只需使用安全导航操作符<p>{{text?}}</p>

export class ChapitreComponent implements OnInit, AfterViewInit {
   ...
   text: String;

   ...
      .then(res: Response) => {
         this.text = res.text
      }
   ...
}


<p>{{text?}}</p>

如果您想覆盖代码中的内容,Angular 2会为您提供非常棒的渲染器!

renderer.setText(this.includeDiv.nativeElement, res.text);

https://angular.io/docs/ts/latest/api/core/index/Renderer-class.html