2015-11-17 13 views
14

私は、ページに動的にtamplateを含める必要があるときはいつでも、角度1でng-includeを使用しています。angular2のtemplatURLの動的テンプレート

今角度2でこれをacheiveする方法を私は探してみましたし、これらを発見した:

https://groups.google.com/forum/#!topic/angular/ROkKDHboWoA

https://github.com/angular/angular/issues/2753

誰かがリンクがNG言うようangular2でこれを行う方法を説明することができますセキュリティ上の理由により、-includeは含まれていません。 veriable値は、テンプレートを提供するために、サーバー側で処理することができるようにtemplateUrlプロパティでveriableを使用する方法

または少なくとも...のよう

+0

このhttp://stackoverflow.com/questions/34457716/dynamic-template-transclusion-in-angular2またはhttpをしてみてください。 com/questions/33034930/how-to-use-angular2-dynamiccomponentloader-in-es6またはhttps://angular.io/docs/ts/latest/api/core/DynamicComponentLoader-class.html – Gary

答えて

11

そして、あなたはおそらく、我々はそれを得ることはありません、角度のレポにこのissueで見ることができるように指令。私たちがこの指令を必要とするかどうか、また私たちがそれをどのように実装できるかについては、長い間議論がありました。

私はそれをどのように実装できるかの簡単な例を作りました。

@Component({ 
    selector: 'my-ng-include', 
    template: '<div #myNgIncludeContent></div>' 
}) 
export class MyNgInclude implements OnInit { 

    @Input('src') 
    private templateUrl: string; 

    @ViewChild('myNgIncludeContent', { read: ViewContainerRef }) 
    protected contentTarget: ViewContainerRef; 

    constructor(private componentResolver: ComponentResolver) {} 

    ngOnInit() { 
     var dynamicComponent = this.createContentComponent(this.templateUrl); 
     this.componentResolver.resolveComponent(dynamicComponent) 
      .then((factory: any) => this.contentTarget.createComponent(factory)); 
    } 

    createContentComponent(templateUrl) { 
     @Component({ 
      selector: 'my-ng-include-content', 
      templateUrl: templateUrl, 
      directives: FORM_DIRECTIVES, 
     }) 
     class MyNgIncludeContent {} 
     return MyNgIncludeContent ; 
    } 
} 

デモチェックの場合はPlunkerです。

+1

動的に作成されたコンポーネントに入力パラメータを設定することはできますか?私は角度1のグリッドを角度2に変換しようとしています。オリジナルはカスタムセルテンプレートを持っていました。私は上記を実装しましたが、動作するバインディングを取得することはできません – Jason

+0

'MyNgIncludeContent'クラスの代わりに既存のクラスが必要です。クラス名はURLと同じように来る。出来ますか? –

+1

@ Jasonあなたは解決策を見つけましたか?私も同じことを探しています。どのように特定の列(テンプレート列はグリッドテンプレートディレクティブかもしれない)のすべてのセルのデータで子要素(HTMLテンプレート)をコンパイルする。 – Karthick

1

alpha.46(およびES6 JS付き): ファイルのインポートファイルで

あなたは、したかった:そのよう

@Component({ 
    selector: 'account' 
}) 
@View({ 
    templateUrl: './folder/containing/template.html' 
}) 

簡単。

コンポーネントをインポートすることを意図している場合、これはあなたがファイルに何をすべきかです:

import ComponentClassName from './folder/with/componentName'; 

...

@View({ 
    directives: [ComponentClassName] 
}) 

そして子のインポートファイル内 /コンポーネント:

ComponentClassNameを定義してください(templateUrlから@Viewまで)。

ファイルの末尾にあるexport default ComponentClassName;を忘れないでください。

公式のAngular 2文書には例はあまりありませんが、あなたはそれを偶然見つけますevery once in a while

+0

私が尋ねた質問はそうではありません...私はテンプレートを追加する方法を知っています...私が望むのは、要件ごとに異なるテンプレートをインポートする唯一のコンポーネントです。これは、ng-includeを使用して角度1で可能でした。 – binariedMe

+0

次に、簡単な答えは** no **です。あなた自身の研究が示しているように、Angularチームは設計通りにngIncludeを削除しました。 [ng-includeを実装することはもはや不可能です。コンパイラはHTMLをコンパイルするためにComponentDirectiveを必要とします。そのため、HTMLを単独でコンパイルしてビューに含めることはできません。](http://eisenbergeffect.bluespire.com/all-about-angular-2-0/) – sdnyco

+0

提案する可能性のある回避策... – binariedMe

3

実際には角度2は現在のビルドでこれを特色にしていません。また、追加されたリンクごとに、私はこの機能が含まれるとは思わない。

ajax呼び出しを使用してテンプレートを動的に追加するためのjavascriptを使用できます。

今後、ダイナミックテンプレートローダーライブラリを使用できるようになります。

+0

カスタムディレクティブを使用してみませんか? – Wtower

+0

これも可能で、より良いです。提案していただきありがとうございます。実際には「JavaScriptの部分」によって私は同じことを意味していました。 – binariedMe

+0

クール、ありがとう。コードサンプルで回答を投稿する。 – Wtower

2

@binariedMeが正確に説明しているように、ng-includeはセキュリティ上の理由から角度2でオフになっています。推奨される方法は、わずかなプログラミングオーバーヘッドを伴うカスタムディレクティブを使用することです。

さらに、角度コード2を準備する。0:

myApp.directive('myInclude', function() { 
    return { 
     templateUrl: 'mytemplate.html' 
    }; 
}); 

むしろ要素にng-includeを使用するよりも、単にmy-includeを追加します。

<div my-include></div> 
+0

何ですか?この角2のコードですか? – newman

+0

@newman明らかに、指摘してくれてありがとう。答えで明確にされた。 – Wtower

0

@binariedMeとこのブログ投稿http://blog.lacolaco.net/post/dynamic-component-creation-in-angular-2/に続いて、私はあなたのために役立つ解決法を構築することができました。 AJAX呼び出しを使用し、返されたHTMLコンテンツからカスタムコンポーネントを動的に作成すると、新しいmy-ng-includeカスタムディレクティブを作成する際にこの問題が解決されます。次のように

import { 
    Component, 
    Directive, 
    ComponentFactory, 
    ComponentMetadata, 
    ComponentResolver, 
    Input, 
    ReflectiveInjector, 
    ViewContainerRef 
} from '@angular/core'; 
import { Http } from '@angular/http'; 

export function createComponentFactory(resolver: ComponentResolver, metadata: ComponentMetadata): Promise<ComponentFactory<any>> { 
    const cmpClass = class DynamicComponent {}; 
    const decoratedCmp = Component(metadata)(cmpClass); 
    return resolver.resolveComponent(decoratedCmp); 
} 

@Directive({ 
    selector: 'my-ng-include' 
}) 
export class MyNgInclude { 

    @Input() src: string; 

    constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver, private http: Http) { 
    } 

    ngOnChanges() { 
     if (!this.src) return; 

     this.http.get(this.src).toPromise().then((res) => { 
     const metadata = new ComponentMetadata({ 
      selector: 'dynamic-html', 
      template: res.text(), 
     }); 
     createComponentFactory(this.resolver, metadata) 
      .then(factory => { 
      const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector); 
      this.vcRef.createComponent(factory, 0, injector, []); 
      }); 
     }); 
    } 
} 

は単にそれを使用:// stackoverflowの:

<my-ng-include [src]="someChangingProperty"></my-ng-include> 
+0

残念ながら、ComponentMetadataとComponentResolverはAngular v2.0.0 +で削除されました。 –

関連する問題