通过注入的innerHTML

时间:2018-10-30 04:47:55

标签: angular

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

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

因此,您正在使用innerHTML渲染动态html,并且您可能发现使用innerHTML时角度代码不起作用。对?而且,如果您在href标记中使用anchor属性,则单击该属性将使您的应用程序再次加载。

这可能是一个矫kill过正,但是您使用 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],可以使用。
  • 请勿盲目复制粘贴,使用前您需要研究吗?