Dynamic template in templatURL in angular2

前端 未结 5 947
醉话见心
醉话见心 2020-11-30 06:52

I have been using ng-include in angular 1 whenever I had to include a tamplate dynamically in the page.

Now how to acheive this in angular 2. I have tried searching

相关标签:
5条回答
  • 2020-11-30 07:20

    Actually angular 2 has not featured this in the current build. Also as per the links added, I don't think this feature will be included.

    A piece of javascript to dynamically add template using ajax call may be used.

    Or possibly in future a dynamic template loader library will be available for use.

    0 讨论(0)
  • 2020-11-30 07:30

    As of alpha.46 (and with ES6 JS):

    In the parent file import file you wanted to include:

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

    Easy as that.

    If you meant to import a component, this is what you do in the parent file:

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

    ...

    @View({
      directives: [ComponentClassName]
    })
    

    And inside the imported file of the child/component:

    Define your ComponentClassName (you may add templateUrlto the @View just as demonstrated at the top).

    Don't forget to export default ComponentClassName; at the bottom of the file.

    There are not many examples in the official Angular 2 docs, but you stumble across it every once in a while.

    0 讨论(0)
  • 2020-11-30 07:31

    Following @binariedMe and this blog post http://blog.lacolaco.net/post/dynamic-component-creation-in-angular-2/, I was able to construct a solution that may work for you. Using an AJAX call and creating the custom component dynamically from the returned html content should fix this problem in creating a new my-ng-include custom directive.

    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, []);
              });
          });
        }
    }
    

    Just simply use it as follows:

    <my-ng-include [src]="someChangingProperty"></my-ng-include>
    
    0 讨论(0)
  • 2020-11-30 07:33

    As @binariedMe accurately describes, ng-include is off in Angular 2 due to security considerations. The recommended method is to use a custom directive with slightly more programmatical overhead.

    Additionally, to prepare your Angular code for 2.0:

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

    And rather than using ng-include on an element, simply add my-include:

    <div my-include></div>
    
    0 讨论(0)
  • 2020-11-30 07:40

    And as you can see in this issue on the Angular repo, most probably we won't get that directive. There has been a long discussion whether we need this directive or not, and if not provided how we can implement it by our self.

    I tried to make a simple example of how it can be implemented.

    @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 ;
        }
    }
    

    For a demo check this Plunker.

    0 讨论(0)
提交回复
热议问题