我想手动编译一些包含指令的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);
我知道这个问题已经很久了,但是我花了数周的时间试图弄清楚如何在启用AOT的情况下进行此工作。我能够编译一个对象,但无法执行现有组件。好吧,我最终决定更改策略,因为我不希望像执行自定义模板那样大量地编译代码。我的想法是添加任何人都可以做并循环通过现有工厂的html。这样,我可以搜索element / attribute / etc。在该HTMLElement上命名并执行组件。我能够使它工作,并认为我应该分享它,以节省我浪费在它上面的大量时间。
@Component({
selector: "compile",
template: "",
inputs: ["html"]
})
export class CompileHtmlComponent implements OnDestroy {
constructor(
private content: ViewContainerRef,
private injector: Injector,
private ngModRef: NgModuleRef<any>
) { }
ngOnDestroy() {
this.DestroyComponents();
}
private _ComponentRefCollection: any[] = null;
private _Html: string;
get Html(): string {
return this._Html;
}
@Input("html") set Html(val: string) {
// recompile when the html value is set
this._Html = (val || "") + "";
this.TemplateHTMLCompile(this._Html);
}
private DestroyComponents() { // we need to remove the components we compiled
if (this._ComponentRefCollection) {
this._ComponentRefCollection.forEach((c) => {
c.destroy();
});
}
this._ComponentRefCollection = new Array();
}
private TemplateHTMLCompile(html) {
this.DestroyComponents();
this.content.element.nativeElement.innerHTML = html;
var ref = this.content.element.nativeElement;
var factories = (this.ngModRef.componentFactoryResolver as any)._factories;
// here we loop though the factories, find the element based on the selector
factories.forEach((comp: ComponentFactory<unknown>) => {
var list = ref.querySelectorAll(comp.selector);
list.forEach((item) => {
var parent = item.parentNode;
var next = item.nextSibling;
var ngContentNodes: any[][] = new Array(); // this is for the viewchild/viewchildren of this object
comp.ngContentSelectors.forEach((sel) => {
var ngContentList: any[] = new Array();
if (sel == "*") // all children;
{
item.childNodes.forEach((c) => {
ngContentList.push(c);
});
}
else {
var selList = item.querySelectorAll(sel);
selList.forEach((l) => {
ngContentList.push(l);
});
}
ngContentNodes.push(ngContentList);
});
// here is where we compile the factory based on the node we have
let component = comp.create(this.injector, ngContentNodes, item, this.ngModRef);
this._ComponentRefCollection.push(component); // save for our destroy call
// we need to move the newly compiled element, as it was appended to this components html
if (next) parent.insertBefore(component.location.nativeElement, next);
else parent.appendChild(component.location.nativeElement);
component.hostView.detectChanges(); // tell the component to detectchanges
});
});
}
}
同时使用AOT + JIT。
我在这里创建了如何使用它:https : //github.com/patrikx3/angular-compile
npm install p3x-angular-compile
组件:应该具有上下文和一些html数据...
HTML:
<div [p3x-compile]="data" [p3x-compile-context]="ctx">loading ...</div>
您可以看到该组件,该组件允许编译简单的动态Angular组件https://www.npmjs.com/package/@codehint-ng/html-compiler
如果要注入html代码,请使用指令
If you want to load whole component in some place, use DynamicComponentLoader:
https://angular.io/docs/ts/latest/api/core/DynamicComponentLoader-class.html