【问题标题】:Using Angular4 Router from injected innerHTML从注入的 innerHTML 使用 Angular4 路由器
【发布时间】:2018-10-30 04:47:55
【问题描述】:

我正在使用 Angular4 并从使用 [innerHtml] 显示在 div 标记中的 XHR 请求返回 html。

它是安全的 html,所以我将 DomSanitizer 与 bypassSecurityTrustHtml 一起使用,这样我就可以在 html 中包含 JavaScript。

我想在返回的 html 中包含指向 Angular 应用程序中位置的链接。即通过路由器。

问题:有没有办法从返回的 html 中触发 Angular 函数,以便我可以调用路由器?还是有更好的办法?

谢谢!

【问题讨论】:

    标签: angular


    【解决方案1】:

    所以您正在使用innerHTML 渲染动态html,并且您可能发现使用innerHTML 时角度代码不起作用。正确的?如果您在anchor 标签中使用href 属性,点击它会再次加载您的应用程序。

    这可能有点矫枉过正,但您使用 RuntimeComponent。

    基本上:

    • 你创建了一个RuntimeComponentModule
    • 获取ComponentFactory
    • 实例化单个组件并将其宿主视图插入到您的容器中。

    示例代码如下:

    app.component.html

    <div #container></div>
    <router-outlet></router-outlet>
    

    app.component.ts

    @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
    })
    export class AppComponent {
        title = 'app';
        @ViewChild('container', {read: ViewContainerRef}) container: ViewContainerRef;
        private componentRef: ComponentRef<{}>;
    
        constructor(private compiler: Compiler) { }
    
        ngOnInit(): void {
            const template = `
                <h1>Check Header H1</h1>
                <a [routerLink]='["/a"]'>Go to A</a>
                <a [routerLink]='["/b"]'>Go to B</a>
            `;
            const data = [];
            this.createComponent(template, data);
        }
    
        createComponent(_template, _data): any {
            let metadata = {
                template: _template
            };
    
            let factory = this.createComponentFactorySync(metadata, null, _data);
            if(this.componentRef){
                this.componentRef.destroy();
                this.componentRef = null;
            }
            this.componentRef = this.container.createComponent(factory);
        }
    
        createComponentFactorySync(metadata: Component, componentClass: any, inputdata: any): ComponentFactory<any> {
            const cmpClass = componentClass || class RuntimeComponent { /*Component declaration*/
                name: string = "C1"; data: any = inputdata
                ngOnInit(): void {
                    console.log('ngOnInit()')
                }
    
                ngOnDestroy(): void {
                    console.log('ngOnDestroy()');
                }
            };
            const typeD: TypeDecorator = Component(metadata);
            const decoratedCmp = typeD(cmpClass);
            @NgModule({imports: [RouterModule], declarations: [decoratedCmp]}) /*import RouterModule for RouterLink to work*/
            class RuntimeComponentModule {}
            let module: ModuleWithComponentFactories<any> = this.compiler.compileModuleAndAllComponentsSync(RuntimeComponentModule);
            return module.componentFactories.find(f => f.componentType === decoratedCmp);
        }
    }
    

    app.module.ts

    const appRoutes:Routes = [
        { path: '', redirectTo: 'a', pathMatch:'full'},
        { path: 'a', component: AComponent},
        { path: 'b',component: BComponent},
    ]
    

    注意:

    • 与您不同,我已将应用程序组件的 div #container 在运行时创建。但是,它的 html 模板中有 a [routerLink] 可以工作。
    • 不要盲目复制粘贴,使用前自己研究一下。

    【讨论】:

    • 谢谢,你真好。我早上去看看:)
    猜你喜欢
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2016-09-10
    • 2017-12-07
    • 2022-06-22
    • 1970-01-01
    相关资源
    最近更新 更多