繁体   English   中英

如何使用组件将动态 HTML 加载到 DIV 中? 角5

[英]How to load dynamic HTML into DIV with component? Angular5

这两天我一直在努力寻找这个问题的解决方案。 不幸的是,我无法得到我想要的。 我正在使用 Angular5。

<div class="form-group col-md-12" [innerHTML]="GetItemsOfHolder(item.children[1],1,
'UserConfigGroupsLabelHolder') | keepHtml"></div>

这是我的函数的样子:

GetItemsOfHolder(item: any,divName:string, recursive: boolean = false,typeName:string="") 
{
return html;
}

一切正常,除非我返回的 html 包含一个名为Select2 的包。这是我用来将 html 添加到这个 div 中的方法,它工作得很好。 直到我想添加动态包。

我的意思是返回 html 包含这样的包组件:

itemhtml +="<select2 data-type='"+holderItem.itemType+"' 
[data]='this.dropdownData."+holderItem.name+"'></select2>"  

这只是将纯文本返回给浏览器,并不能按预期工作。

我想要的是将字符串转换为组件或任何其他工作方式并生成 select2 下拉列表的方式。

我一直在尝试搜索很多东西。但它不起作用这很好,但我无法理解这一点并且不推荐使用动态组件加载。

任何人都可以给我一个想法我该如何解决这个问题? 任何例子都会很棒。

正如@Devcon 所评论的

Angular 会清理几乎所有内容,所以这就是您获得纯文本的原因。 您要研究的是 ReflectiveInjector,主要是 ComponentFactoryResolver。 主要思想是组件需要一些其他信息(服务、其他组件等)来呈现,因此您使用注入器来获取依赖注入引用,然后组件工厂构建您的组件。 然后将其插入到 ViewChild 引用中。 有一种更复杂的动态制作组件的方法,它使用编译器并需要一个 ModuleWithComponentFactories,这就是 angular 实际使用的。

在角度上搜索,我接受角度不应该这样做。

因为我必须创建必须以 html 呈现的完全动态页面。 我稍微改变了我的 json 并使用ng-containerng-template并使用ngswitch我在它自己的模板中进行了递归调用,发现它工作得很好。

使用它我有很多优点:HTML(我动态渲染)本身是 HTML,代码干净可读,易于维护。

此处给出的示例与我所做的几乎相同。 https://stackoverflow.com/a/40530244/2630817

一个小例子在这里:

<ng-template #itemsList let-itemsList>
  <div *ngFor="let item of itemsList;let i = index">
    <div [ngSwitch]="item.itemType">
        <div class="form-group" *ngSwitchCase="'TEXT'">
            <label>
                {{item.label}}
              </label>
              <input id="{{item.name}}" value="{{item.value}}" type='text' class='form-control txtbox ui-autocomplete-input'/>
        </div>
        <div class="form-group" *ngSwitchCase="'PASSWORD'">
            <label>
                {{item.label}}
              </label>
              <input id="{{item.name}}" value="{{item.value}}" type='password' class='form-control txtbox ui-autocomplete-input'/>
        </div>
        <div class="form-group" *ngSwitchCase="'BOOLEAN'">
            <label style='width:40%'>{{item.label}}</label>
            <div class="form-group"><input id="{{item.name}}" type='checkbox' /></div>

        </div>
        <div  class="form-group" *ngSwitchCase="'LABEL'">
            <label class="form-control">{{item.label}}</label>
        </div>
        <div class="form-group"  *ngSwitchDefault>
            <label>
                {{item.label}}
              </label>
              <select2 class="form-control"  [data]="GetDropDowndata(item.holderId)" [cssImport]="false" [width]="300" [options]="GetOptions(item.type)"></select2>
          </div>
    </div>
  </div>

您可以在一个 div 中加载您想要的所有内容,您必须使用 ng-template 和 ng-content。

首先,您必须创建一个指令:

 import {Directive, ViewContainerRef} from '@angular/core'; @Directive({ selector: '[dynamic]', exportAs: 'dynamicdirective' }) export class DynamicDirective { constructor(public viewContainerRef: ViewContainerRef) { } }

在您必须将其放入一些 ng-template 之后,例如:

 <p> page works! </p> <ng-template #sider=dynamicdirective dynamic></ng-template>

并像使用它一样

 import {Component, ComponentFactoryResolver, OnInit, ViewChild} from '@angular/core'; @Component({ selector: 'app-page', templateUrl: './page.component.html', styleUrls: ['./page.component.css'] }) export class PageComponent implements OnInit { @ViewChild('sider') sider; constructor(private componentFactoryResolver: ComponentFactoryResolver) { } ngOnInit() { const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SomeComponent); this.sider.viewContainerRef.createComponent(componentFactory); }); } }

通常会在 ng-template 的位置看到你的组件加载(如果你想重置你的视图,你可以调用https://angular.io/api/core/ViewContainerRef#clear

我已经玩过了,你可以在这里找到一些代码https://github.com/nicearma/dynamic

我想把这个留在这里给将来遇到同样问题的人。

如果您不想像其他答案所建议的那样使用ComponentFactory手动实例化组件,您还可以使用我为将组件加载到动态内容中而编写的明确目的的库: ngx-dynamic-hooks

你可以给它任何包含所需组件选择器的字符串,它会自动加载到它的位置。 您甚至可以通过其他文本模式加载组件,而不仅仅是它们的选择器! 在此 Stackblitz 中查看它的实际效果

如果你需要的话,还有更多的花里胡哨。 在上面的链接中,您会找到一份相当详细的文档,可以轻松地进行设置。

暂无
暂无

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

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