Equivalent of $compile in Angular 2

后端 未结 9 793
名媛妹妹
名媛妹妹 2020-11-21 06:50

I want to manually compile some HTML containing directives. What is the equivalent of $compile in Angular 2?

For example, in Angular 1, I could dynamic

相关标签:
9条回答
  • 2020-11-21 07:16

    this npm package made it easier for me: https://www.npmjs.com/package/ngx-dynamic-template

    usage:

    <ng-template dynamic-template
                 [template]="'some value:{{param1}}, and some component <lazy-component></lazy-component>'"
                 [context]="{param1:'value1'}"
                 [extraModules]="[someDynamicModule]"></ng-template>
    
    0 讨论(0)
  • 2020-11-21 07:19

    I know this issue is old, but I spent weeks trying to figure out how to make this work with AOT enabled. I was able to compile an object but never able to execute existing components. Well I finally decided to change tact, as I was't looking to compile code so much as execute a custom template. My thought was to add the html which anyone can do and loop though the existing factories. In doing so I can search for the element/attribute/etc. names and execute the component on that HTMLElement. I was able to get it working and figured I should share this to save someone else the immense amount of time I wasted on it.

    @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
                });
            });
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:22

    Angular TypeScript/ES6 (Angular 2+)

    Works with AOT + JIT at once together.

    I created how to use it here: https://github.com/patrikx3/angular-compile

    npm install p3x-angular-compile
    

    Component: Should have a context and some html data...

    Html:

    <div [p3x-compile]="data" [p3x-compile-context]="ctx">loading ...</div>
    
    0 讨论(0)
提交回复
热议问题