web-dev-qa-db-ja.com

angular2でHTMLテンプレートを動的にロードする

次のようにAppComponentを含むangular-cliを使用してプロジェクトを作成しました。

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';
}

そしてapp.component.htmlとして

<h1>
  Good Morning, {{title}}
</h1>

したがって、ng buildでビルドすると、次のようなコードを含むこのようなファイル./ dist/main.bundle.jsが生成されます。 -

/* 586 */
/***/ function(module, exports) {

module.exports = "<h1>\n  Good Morning, {{title}}\n</h1>\n"

/***/ },
/* 587 */

つまり、ビルド時に、コンパイラ/バンドル-erはhtmlファイルを読み取り、それらを生成されたjsファイルに連結します。

しかし、私の場合、htmlもdynamicであり、サーバー側からコンテンツ駆動型です。 htmlの代わりに、私のテンプレートファイルはapp.component.jspであり、いくつかの異なるサーバーまたはフォルダー全体に存在するとしましょう。

また、そのJSPファイルは、現在のサーバー時間に応じて<h1>Good Morning, {{title}}</h1>および<h1>Good Afternoon, {{title}}</h1>を返す場合があります。

この機能を実現するには?

私が理解しているのは、ある種のローダー関数を定義する必要があるということです:loadDynamicTemplate(template_url)

コンポーネントデコレータテンプレートプロパティでそのローダー関数を使用する必要があります。その場合、main.bundle.JSが生成されると、その関数も使用されます。そのため、実行時にangularはこの関数を呼び出し、ajaxによってHTMLをロードして使用します。

アップデート1

ここ SystemJSとWebpackの違いを見つけました。 SystemJSを使用できる場合は、実行時にHTMLファイルをロードできることもわかりました。したがって、この問題はSystemJS構成で解決できると思います。しかし、そのためには別の問題が発生しますが、それは別の問題になると思います。そこで、私はそれを整理するための新しい質問を投稿しました here

おそらくその質問が解決された場合、SystemJSを試して、それが役立つ場合はここに解決策を投稿します。

44

次のようなものでmy-templateコンポーネントで[innerHtml]を使用できます(テストしませんでした)。

@Component({
    selector: 'my-template',
    template: `
<div [innerHtml]="myTemplate">
</div>
`})
export public class MyTemplate {
    private myTemplate: any = "";
    @Input() url: string;
    constructor(http: Http) {
        http.get("/path-to-your-jsp").map((html:any) => this.myTemplate = html);
    }
}
35
Karbos 538

テンプレートをいくつかのGood Morning, {{title}}で補間するには、稲富卓の「ng-dynamic」コンポーネントを使用できます。

最初にインストールする必要があります:

npm install --save ng-dynamic

次に、NgModuleにインポートします。

@NgModule({
  imports: [
    ...
    DynamicComponentModule.forRoot({}),
    ...
  ],
  ...
})
export class AppModule {}    

最後にこのように使用します:

@Component({
  selector: 'app-root',
  template: '<div *dynamicComponent="template; context: bindings;"></div>'
})
export class AppComponent {
  bindings: any = {title: "Chuck Norris"};
  template: string = `
    <h1>Good Morning, {{title}}</h1>
  `;
  constructor(http: Http) {
    http.get("/path-to-your-jsp").map((html:string) => this.template = html); //<- You may set bindings in request headers...
  }
}

SharedModuleを定義することにより、テンプレートでコンポーネントを使用できます。ここにドキュメントの例のように成功したカスタム「マイボタン」を追加しました: https://github.com/laco0416/ng-dynamic

18
Karbos 538

これを行う方法は、リクエストを行うときにresponseTypeを設定することであるように見えます。 HttpClient-Requesting non-JSON data `

@Component({
  selector: 'my-template',
  template: '<div [innerHtml]="myTemplate"></div>'
})
export public class MyTemplate {
  private myTemplate: any = "";
  @Input() url: string;
  constructor(http: Http) {
    http.get("/path-to-your-jsp", { responseType: 'text' })
      .subscribe(
        (data: string) => {
          this.myTemplate = html;
        }
      );
  }
}

`

2
nbppp2

angular 6と連携

import { Component, Input } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  template: `
            <div [innerHtml]="myTemplate">
            </div>
          `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private myTemplate: any = '';
  constructor(http: HttpClient) {
    http.get('/service-path', {responseType: 'text'}).subscribe(data => this.myTemplate = data);
  }
}
0
nznoor

すべてのテンプレートを1つのファイルにまとめて、条件に従って表示しないようにしましょう。./ app.component.htmlは次のようになります。

<div *ngIf="isWorld" >
  <h1>  Hello World </h1>
</div>
<div *ngIf="isUniverse" >
  <h1>  Hello Universe </h1>
</div>

ビルド時間/サイズへの影響に関するアイデアはありますか?

0
Kiran