按 [innerHTML] 显示 <my-component>

Display <my-component> by [innerHTML]

我试图将我的自定义组件标签放在一个字符串数组中,并在通过调用 bypassSecurityTrustHtml 对其进行清理后通过 ngfor 将它们绑定到 innerhtml 属性...不幸的是,输出始终为空,但是也没有清理错误...

我做错了什么?

// adminpanel.component.ts
@Component({
    selector: 'admin-panel',
    templateUrl: './adminpanel.component.html'
})
export class AdminPanelComponent {

    static GetRoutes(): Route[] {
        return [
            { path: '', redirectTo: 'news', pathMatch: 'full' },

        // 0
            { path: 'news', component: AdminNewsViewComponent },
        // 1
            { path: 'users', component: AdminUsersViewComponent },
        // 2
            { path: 'roles', component: AdminRolesViewComponent },
        // 3
            {
                path: 'culturesettings',
                redirectTo: 'culturesettings/wordvariables'
            },
            {
                path: 'culturesettings', 
                component: AdminCultureSettingsViewComponent,
                pathMatch: 'prefix',
                children: AdminCultureSettingsViewComponent.GetRoutes()
            },
        // 4
            {
                path: 'account',
                component: AdminAccountViewComponent
            }
        ]
    }

    panels: AdminPanel[] = [];

    routedTabs: RoutedTabs

    constructor(private authService: AuthService, private routerService: RouterService, private sanitizer: DomSanitizer) {
        this.routedTabs = new RoutedTabs("admin/panel", 2, authService, routerService);

        var routes = AdminPanelComponent.GetRoutes().filter(x => x.component != undefined);
        var comps = [
            '<admin-news-view></admin-news-view>',
            '<admin-users-view></admin-users-view>',
            '<admin-roles-view></admin-roles-view>',
            '<admin-culture-settings-view></admin-culture-settings-view>',
            '<admin-account-view></admin-account-view>'
        ];
        for (var i = 0; i < comps.length; i++) this.panels.push(new AdminPanel(i, routes[i], this.sanitizer.bypassSecurityTrustHtml(comps[i])  , this.sanitizer));

    }

    ngOnInit() {

        this.routedTabs.MakeTabs(AdminPanelComponent.GetRoutes());
        this.routedTabs.Subscribe();
        this.routedTabs.Emit();
    }
    ngOnDestroy() {
        this.routedTabs.Unsubscribe()
    }
}
class AdminPanel {
    index: number;
    route: Route;
    innerHtml: any = '';
    constructor(index: number, route: Route, innerHtml: any, private sanitizer: DomSanitizer) {
        this.index = index;
        this.route = route;
        this.innerHtml = innerHtml;

    }
}

在我的 adminpanel.component.html 中:

<mat-tab-group (selectedTabChange)="routedTabs.onTabChange($event)" [(selectedIndex)]="routedTabs.selectedTab">
    <mat-tab *ngFor="let panel of panels" label="{{ routedTabs.tabs[panel.index].label }}">
        <div [innerHTML]="panel.innerHtml">

        </div>
    </mat-tab>
</mat-tab-group>

仅将标签用作字符串是行不通的,因为如果 dom 中弹出具有匹配选择器的元素,angular 不仅会创建组件实例。

你要么

  1. 使用ComponentFactoryResolver
  2. 面板上只有一个类型 属性,因此您可以根据类型使用 ngSwitch 并在 ngSwitchCase 中呈现相应的内容。在那种情况下,你的模板中会有标签

据我所知,这并没有真正以令人满意或干净的方式得到解决。我一直在同一条船上,也没有找到在动态字符串中加载组件的好解决方案 - 所以我用 ngx-dynamic-hooks!

编写了自己的解决方案

您可能感兴趣的一些要点:

  • 查找字符串中的所有组件选择器并自动将相应的组件加载到它们的位置
  • 如果您需要的话,甚至可以通过选择器之外的其他文本模式加载组件
  • 输入和输出可以像在普通模板中一样设置,并自动从字符串解析为实际变量
  • 组件可以不受限制地嵌套,并且会出现在彼此的“ng-content”-slots 预期中
  • 您可以将实时数据从父组件传递到动态加载的组件中(甚至用它来绑定内容字符串中的 inputs/outputs)
  • 您可以精确控制允许在 outlet-to-outlet-basis 上加载哪些组件,甚至 inputs/outputs 您可以给它们加载哪些组件
  • 您可以选择将组件配置为 lazy-load 仅在需要时
  • 该库使用 Angular 的 built-in DOMSanitizer,即使输入可能不安全也能安全使用

这些组件是使用本机 Angular 方法创建的,其行为与您应用中的任何其他组件一样。希望对遇到同样问题的大家有所帮助

查看实际效果 in this Stackblitz