繁体   English   中英

templatURL中的动态模板,角度为2

[英]Dynamic template in templatURL in angular2

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

现在如何在角度2中实现这一点。我试过搜索并找到了这些:

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

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

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

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

正如你在本期 Angular repo中看到的那样,很可能我们不会得到那个指令。 我们是否需要这个指令已经进行了长时间的讨论,如果没有提供我们如何通过自己实现它。

我试图给出一个如何实现它的简单例子。

@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

实际上,角度2在当前构建中没有这个特征。 另外,根据添加的链接,我认为不会包含此功能。

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

或者将来可能会使用动态模板加载器库。

截至alpha.46 (和ES6 JS):

在您要包含的文件导入文件中:

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

很简单。

如果您要导入组件,这是您在文件中执行的操作:

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

...

@View({
  directives: [ComponentClassName]
})

/组件的导入文件中:

定义ComponentClassName (您可以将templateUrl添加到@View ,如上图所示)。

不要忘记export default ComponentClassName; 在文件的底部。

官方的Angular 2文档中没有很多例子,但你每隔一段时间偶然发现它。

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

另外,准备2.0的Angular代码:

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

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

<div my-include></div>

在@binariedMe和这篇博客文章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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM