简体   繁体   English

从注入的innerHTML使用Angular4 Router

[英]Using Angular4 Router from injected innerHTML

I'm using Angular4 and returning html from an XHR request that is displayed in a div tag using [innerHtml]. 我正在使用Angular4,并使用[innerHtml]从div标记中显示的XHR请求返回html。

It's safe html so I'm using the DomSanitizer with bypassSecurityTrustHtml so that I can include JavaScript in the html. 它是安全的html,因此我将DomSanitizer与bypassSecurityTrustHtml一起使用,以便可以在html中包含JavaScript。

I would like to include links in the returned html to locations within the Angular app. 我想在返回的html中包含指向Angular应用内位置的链接。 ie via the router. 即通过路由器。

Question: Is there a way to fire an Angular function from the returned html so that I can call the router? 问题:有没有办法从返回的html中触发Angular函数,以便我可以调用路由器? Or is there a better way? 或者,还有更好的方法?

Thanks! 谢谢!

So you are rendering dynamic html using innerHTML and you probably found out that angular codes won't work when using innerHTML . 因此,您使用innerHTML渲染动态html时,您可能发现使用innerHTML时角度代码不起作用。 Right? 对? And if you use href attribute in anchor tag, clicking on it will for your application to load again. 而且,如果您在anchor标记中使用href属性,则单击该属性将再次加载您的应用程序。

It may be an overkill but you use RuntimeComponent . 这可能是一个矫kill过正,但您使用RuntimeComponent

Basically: 基本上:

  • you create a RuntimeComponentModule 您创建一个RuntimeComponentModule
  • get the ComponentFactory 获取ComponentFactory
  • instantiates a single component and inserts its host view into your container. 实例化单个组件,并将其宿主视图插入到您的容器中。

Sample code below: 下面的示例代码:

app.component.html app.component.html

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

app.component.ts 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 app.module.ts

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

Notice: 注意:

  • Unlike you, I have made app component's div #container to be created at runtime. 与您不同,我使应用程序组件的div #container在运行时创建。 However it has the a [routerLink] in its html template which will work. 但是,它的html模板中有a [routerLink]可以使用。
  • Do not copy paste blindly, do you own research before using it. 不要盲目复制粘贴,使用前要自己研究一下。

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

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