javascript angular2 中 templatURL 中的动态模板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33749994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 16:51:48  来源:igfitidea点击:

Dynamic template in templatURL in angular2

javascriptangular

提问by binariedMe

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

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

Now how to acheive this in angular 2. I have tried searching and found these :

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

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

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

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

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

can someone explain how to do this in angular2 as the link says ng-include is not included due some security reasons.

有人可以解释如何在 angular2 中做到这一点,因为链接说由于某些安全原因不包括 ng-include。

Or atleast how to use a veriable in templateUrl property so that the veriable value can be handled on server side to serve the template...

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

采纳答案by S.Klechkovski

And as you can see in this issueon 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.

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

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.

对于演示,请检查这个Plunker

回答by binariedMe

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.

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

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

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

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

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

回答by Wtower

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

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

Additionally, to prepare your Angular code for 2.0:

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

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

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

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

<div my-include></div>

回答by sdnyco

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

alpha.46(和 ES6 JS)开始:

In the parentfile 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 parentfile:

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

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 @Viewjust as demonstrated at the top).

定义您的ComponentClassName(您可以添加templateUrl@View顶部所示的)。

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

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

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

Angular 2 官方文档中的示例并不多,但您偶尔会偶然发现它。

回答by thejava

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.

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

Just simply use it as follows:

只需简单地使用它如下:

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