angular2中templatURL中的动态模板

Dynamic template in templatURL in angular2

每当我必须在页面中动态包含模板时,我一直在 angular 1 中使用 ng-include。

现在如何在 angular 中实现此目标 2. 我尝试搜索并找到了这些:

https://groups.google.com/forum/#!topic/angular/ROkKDHboWoA ,

https://github.com/angular/angular/issues/2753

有人可以在 angular2 中解释如何执行此操作,因为 link 说由于某些安全原因未包含 ng-include。

或者至少如何在 templateUrl 中使用可验证值 属性 以便可以在服务器端处理可验证值以提供模板...

alpha.46 开始(以及使用 ES6 JS):

parent 文件中导入您想要包含的文件:

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

就这么简单。

如果您打算导入组件,这就是您在 parent 文件中所做的:

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

...

@View({
  directives: [ComponentClassName]
})

并且在 child/component 的导入文件中:

定义您的 ComponentClassName(您可以将 templateUrl 添加到 @View,正如顶部所示)。

别忘了在文件底部export default ComponentClassName;

官方Angular 2文档中的例子不多,但是你偶然发现了every once in a while

实际上 angular 2 在当前版本中没有此功能。另外根据添加的链接,我认为不会包含此功能。

一段 javascript 可以使用 ajax 调用动态添加模板。

或者将来可能会提供动态模板加载程序库。

正如@binariedMe 准确描述的那样,出于安全考虑,ng-include 在 Angular 2 中处于关闭状态。推荐的方法是使用编程开销稍大的自定义指令。

此外,要为 2.0 准备 Angular 代码:

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

而不是在元素上使用 ng-include,只需添加 my-include:

<div my-include></div>

正如您在 Angular 存储库的 issue 中看到的那样,我们很可能不会获得该指令。我们是否需要这个指令已经进行了很长时间的讨论,如果没有提供我们如何自己实现它。

我试着举了一个简单的例子来说明它是如何实现的。

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

如需演示,请查看此 Plunker

关注@binariedMe 和此博客 post http://blog.lacolaco.net/post/dynamic-component-creation-in-angular-2/,我构建了一个可能适合您的解决方案。使用 AJAX 调用并根据返回的 html 内容动态创建自定义组件应该可以在创建新的 my-ng-include 自定义指令时解决此问题。

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

简单使用如下:

<my-ng-include [src]="someChangingProperty"></my-ng-include>