pix*_*its 127 version-compatibility typescript angular2-compiler angular
我想手动编译一些包含HTML的指令.$compileAngular 2中的等价物是什么?
例如,在Angular 1中,我可以动态编译HTML片段并将其附加到DOM:
var e = angular.element('<div directive></div>');
element.append(e);
$compile(e)($scope);
Run Code Online (Sandbox Code Playgroud)
Rad*_*ler 127
要获取所有详细信息,请检查:
要看到这一点:
校长:
1)创建模板
2)创建组件
3)创建模块
4)编译模块
5)创建(和缓存)ComponentFactory
6)使用Target创建它的实例
快速概述如何创建组件
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;
}
Run Code Online (Sandbox Code Playgroud)
一种如何将组件注入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;
}
Run Code Online (Sandbox Code Playgroud)
一个代码片段如何创建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);
});
});
}
Run Code Online (Sandbox Code Playgroud)
一段代码片段如何使用上述结果
// 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;
//...
});
Run Code Online (Sandbox Code Playgroud)
.
.
OBSOLETE - 与Angular 2.0 RC5相关(仅限RC5)
要查看之前RC版本的先前解决方案,请搜索此帖子的历史记录
ale*_*ods 33
注意:正如@BennyBottema在评论中提到的那样,现在不推荐使用DynamicComponentLoader,因此这个答案也是如此.
Angular2没有任何 $ compile等价物.您可以使用DynamicComoponentLoader和破解ES6类来动态编译代码(请参阅此插件):
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'
);
}
}
Run Code Online (Sandbox Code Playgroud)
但只有在html解析器位于angular2核心内部之前它才会起作用.
Cod*_*-EZ 15
我使用的Angular版本 - Angular 4.2.0
Angular 4提供了ComponentFactoryResolver来在运行时加载组件.这是Angular 1.0 中$ compile的一种相同实现, 可满足您的需求
在下面的示例中,我将ImageWidget 组件动态加载到DashboardTileComponent中
要加载组件,您需要一个可以应用于ng-template的指令, 这将有助于放置动态组件
WidgetHostDirective
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[widget-host]',
})
export class DashboardTileWidgetHostDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}
Run Code Online (Sandbox Code Playgroud)
此指令注入ViewContainerRef以访问将托管动态添加组件的元素的视图容器.
DashboardTileComponent(用于呈现动态组件的占位符组件)
此组件接受来自父组件的输入,或者您可以根据您的实现从服务加载.该组件在运行时解决组件方面发挥着重要作用.在此方法中,您还可以看到名为renderComponent()的方法,该方法最终从服务加载组件名称,并使用ComponentFactoryResolver解析并最终将数据设置为动态组件.
import { Component, Input, OnInit, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { DashboardTileWidgetHostDirective } from './DashbardWidgetHost.Directive';
import { TileModel } from './Tile.Model';
import { WidgetComponentService } from "./WidgetComponent.Service";
@Component({
selector: 'dashboard-tile',
templateUrl: 'app/tile/DashboardTile.Template.html'
})
export class DashboardTileComponent implements OnInit {
@Input() tile: any;
@ViewChild(DashboardTileWidgetHostDirective) widgetHost: DashboardTileWidgetHostDirective;
constructor(private _componentFactoryResolver: ComponentFactoryResolver,private widgetComponentService:WidgetComponentService) {
}
ngOnInit() {
}
ngAfterViewInit() {
this.renderComponents();
}
renderComponents() {
let component=this.widgetComponentService.getComponent(this.tile.componentName);
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);
let viewContainerRef = this.widgetHost.viewContainerRef;
let componentRef = viewContainerRef.createComponent(componentFactory);
(<TileModel>componentRef.instance).data = this.tile;
}
}
Run Code Online (Sandbox Code Playgroud)
DashboardTileComponent.html
<div class="col-md-2 col-lg-2 col-sm-2 col-default-margin col-default">
<ng-template widget-host></ng-template>
</div>
Run Code Online (Sandbox Code Playgroud)
WidgetComponentService
这是一个服务工厂,用于注册要动态解析的所有组件
import { Injectable } from '@angular/core';
import { ImageTextWidgetComponent } from "../templates/ImageTextWidget.Component";
@Injectable()
export class WidgetComponentService {
getComponent(componentName:string) {
if(componentName==="ImageTextWidgetComponent"){
return ImageTextWidgetComponent
}
}
}
Run Code Online (Sandbox Code Playgroud)
ImageTextWidgetComponent(我们在运行时加载的组件)
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'dashboard-imagetextwidget',
templateUrl: 'app/templates/ImageTextWidget.html'
})
export class ImageTextWidgetComponent implements OnInit {
@Input() data: any;
constructor() { }
ngOnInit() { }
}
Run Code Online (Sandbox Code Playgroud)
添加最后将此ImageTextWidgetComponent作为entryComponent添加到您的app模块中
@NgModule({
imports: [BrowserModule],
providers: [WidgetComponentService],
declarations: [
MainApplicationComponent,
DashboardHostComponent,
DashboardGroupComponent,
DashboardTileComponent,
DashboardTileWidgetHostDirective,
ImageTextWidgetComponent
],
exports: [],
entryComponents: [ImageTextWidgetComponent],
bootstrap: [MainApplicationComponent]
})
export class DashboardModule {
constructor() {
}
}
Run Code Online (Sandbox Code Playgroud)
TileModel
export interface TileModel {
data: any;
}
Run Code Online (Sandbox Code Playgroud)
这个npm包让我更容易:https: //www.npmjs.com/package/ngx-dynamic-template
用法:
<ng-template dynamic-template
[template]="'some value:{{param1}}, and some component <lazy-component></lazy-component>'"
[context]="{param1:'value1'}"
[extraModules]="[someDynamicModule]"></ng-template>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
61877 次 |
| 最近记录: |