ディレクティブを含む HTML を手動でコンパイルしたいと考えています。$compile
Angular 2に相当するものは何ですか?
たとえば、Angular 1 では、HTML のフラグメントを動的にコンパイルして DOM に追加できました。
var e = angular.element('<div directive></div>');
element.append(e);
$compile(e)($scope);
ディレクティブを含む HTML を手動でコンパイルしたいと考えています。$compile
Angular 2に相当するものは何ですか?
たとえば、Angular 1 では、HTML のフラグメントを動的にコンパイルして DOM に追加できました。
var e = angular.element('<div directive></div>');
element.append(e);
$compile(e)($scope);
すべての詳細を確認するには:
実際の動作を確認するには:
プリンシパル:
1) テンプレートを作成
2) コンポーネントを作成
3) モジュールを作成
4) モジュールをコンパイル
5) ComponentFactory を作成 (およびキャッシュ)
6) ターゲットを使用してそのインスタンスを作成
コンポーネントの作成方法の簡単な概要
createNewComponent (tmpl:string) {
@Component({
selector: 'dynamic-component',
template: tmpl,
})
class CustomDynamicComponent implements IHaveDynamicData {
@Input() public entity: any;
};
// a component for this particular template
return CustomDynamicComponent;
}
NgModule にコンポーネントを注入する方法
createComponentModule (componentType: any) {
@NgModule({
imports: [
PartsModule, // there are 'text-editor', 'string-editor'...
],
declarations: [
componentType
],
})
class RuntimeComponentModule
{
}
// a module for just this Type
return RuntimeComponentModule;
}
を作成(およびキャッシュ)する方法のコード スニペットComponentFactory
public createComponentFactory(template: string)
: Promise<ComponentFactory<IHaveDynamicData>> {
let factory = this._cacheOfFactories[template];
if (factory) {
console.log("Module and Type are returned from cache")
return new Promise((resolve) => {
resolve(factory);
});
}
// unknown template ... let's create a Type for it
let type = this.createNewComponent(template);
let module = this.createComponentModule(type);
return new Promise((resolve) => {
this.compiler
.compileModuleAndAllComponentsAsync(module)
.then((moduleWithFactories) =>
{
factory = _.find(moduleWithFactories.componentFactories
, { componentType: type });
this._cacheOfFactories[template] = factory;
resolve(factory);
});
});
}
上記の結果を使用するコード スニペット
// here we get Factory (just compiled or from cache)
this.typeBuilder
.createComponentFactory(template)
.then((factory: ComponentFactory<IHaveDynamicData>) =>
{
// Target will instantiate and inject component (we'll keep reference to it)
this.componentRef = this
.dynamicComponentTarget
.createComponent(factory);
// let's inject @Inputs to component instance
let component = this.componentRef.instance;
component.entity = this.entity;
//...
});
ここで読むすべての詳細を含む完全な説明、または実際の例を観察してください
.
.
OBSOLETE - Angular 2.0 RC5 関連 (RC5 のみ)
以前の RC バージョンの以前の解決策を確認するには、この投稿の履歴を検索してください。
注: @BennyBottema がコメントで言及しているように、DynamicComponentLoader は廃止されたため、この回答も廃止されました。
Angular2 には$compileに相当するものはありません 。ES6 クラスを使用DynamicComoponentLoader
およびハックして、コードを動的にコンパイルできます (このplunkを参照)。
import {Component, DynamicComponentLoader, ElementRef, OnInit} from 'angular2/core'
function compileToComponent(template, directives) {
@Component({
selector: 'fake',
template , directives
})
class FakeComponent {};
return FakeComponent;
}
@Component({
selector: 'hello',
template: '<h1>Hello, Angular!</h1>'
})
class Hello {}
@Component({
selector: 'my-app',
template: '<div #container></div>',
})
export class App implements OnInit {
constructor(
private loader: DynamicComponentLoader,
private elementRef: ElementRef,
) {}
ngOnInit() {} {
const someDynamicHtml = `<hello></hello><h2>${Date.now()}</h2>`;
this.loader.loadIntoLocation(
compileToComponent(someDynamicHtml, [Hello])
this.elementRef,
'container'
);
}
}
ただし、htmlパーサーがangular2コア内にあるまでのみ機能します。
コンポーネントのインスタンスを動的に作成して DOM にアタッチするには、次のスクリプトを使用でき、Angular RCで動作する必要があります。
html テンプレート:
<div>
<div id="container"></div>
<button (click)="viewMeteo()">Meteo</button>
<button (click)="viewStats()">Stats</button>
</div>
ローダー コンポーネント
import { Component, DynamicComponentLoader, ElementRef, Injector } from '@angular/core';
import { WidgetMeteoComponent } from './widget-meteo';
import { WidgetStatComponent } from './widget-stat';
@Component({
moduleId: module.id,
selector: 'widget-loader',
templateUrl: 'widget-loader.html',
})
export class WidgetLoaderComponent {
constructor( elementRef: ElementRef,
public dcl:DynamicComponentLoader,
public injector: Injector) { }
viewMeteo() {
this.dcl.loadAsRoot(WidgetMeteoComponent, '#container', this.injector);
}
viewStats() {
this.dcl.loadAsRoot(WidgetStatComponent, '#container', this.injector);
}
}