通过[innerHTML]显示<my-component>

时间:2018-07-12 18:27:06

标签: javascript angular components ngfor angular-dom-sanitizer

我正在尝试将我的自定义组件标签放置在字符串数组中,并在通过调用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>

2 个答案:

答案 0 :(得分:2)

根据我的收集,这并没有真正以令人满意或干净的方式解决。我一直在同一条船上,也没有找到在动态字符串中加载组件的好方法-所以我用ngx-dynamic-hooks编写了自己的文件!

您可能感兴趣的一些关键点:

  • 在字符串中找到所有组件选择器,并自动将相应的组件加载到它们的位置
  • 如果需要的话,甚至可以通过选择器以外的其他文本模式加载组件
  • 可以像在普通模板中一样设置输入和输出,并自动将字符串从字符串解析为实际变量
  • 组件可以无限制地嵌套,并且可以按预期出现在彼此的“ ng-content”插槽中
  • 您可以将实时数据从父组件传递到动态加载的组件中(甚至使用它来绑定内容字符串中的输入/输出)
  • 您可以精确控制哪些组件可以在插座到插座的基础上装载,甚至可以为它们提供哪些输入/输出
  • 您可以选择将组件配置为仅在需要时才进行延迟加载
  • 该库使用Angular内置的DOMSanitizer来确保即使有潜在的不安全输入也可以安全使用

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

查看实际情况in this Stackblitz

答案 1 :(得分:0)

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

你们要么

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