首页 > 解决方案 > 将 Angular 5 应用程序动态注入 iframe 时,“选择器应用程序根不匹配任何元素”

问题描述

我们有一个独特的情况,我们手动将 iframe 注入到包含 Angular 5 应用程序的页面中。用户可以将此 Javascript 文件包含到任何 HTML 页面上,然后再注入 iframe。如果我硬编码,我不会得到错误。但是,如果我使用以下代码注入 iframe,则会收到以下错误。Angular 应用程序似乎在注入 iframe 之前就在寻找 app-root 元素(如果我在 injectIframe() 方法中放置了一个断点,则会在触发断点之前出现错误)。

VM4116 apm.min.js:16045 ERROR Error: The selector "app-root" did not match any elements
    at DefaultDomRenderer2.webpackJsonp.x35b.DefaultDomRenderer2.selectRootElement (VM4116 apm.min.js:43560)
    at BaseAnimationRenderer.webpackJsonp.x35b.BaseAnimationRenderer.selectRootElement (VM4116 apm.min.js:64508)
    at createElement (VM4116 apm.min.js:25018)
    at createViewNodes (VM4116 apm.min.js:28161)
    at createRootView (VM4116 apm.min.js:28089)
    at Object.createProdRootView [as createRootView] (VM4116 apm.min.js:28784)
    at ComponentFactory_.webpackJsonp.WT6e.ComponentFactory_.create (VM4116 apm.min.js:25702)
    at ComponentFactoryBoundToModule.webpackJsonp.WT6e.ComponentFactoryBoundToModule.create (VM4116 apm.min.js:18612)
    at ApplicationRef.webpackJsonp.WT6e.ApplicationRef.bootstrap (VM4116 apm.min.js:20418)
    at VM4116 apm.min.js:20154

有没有办法在 iframe 完成加载后手动引导应用程序或其他东西,以便在调用 injectIframe 之前不寻找它?

这是注入 iframe 的 Javascript(包含在父窗口的脚本中):

  function injectIFrame(sessionId) {
    // Create the iframe
    var container;
    var containerStyle = '';

    if (typeof iframe === 'undefined') {
      container = document.createElement('iframe');
    }

    // Style the iframe
    containerStyle += 'width: 100%;';
    containerStyle += 'border: none;';
    container.style.cssText = containerStyle;

    container.title = "APM";
    container.src = 'https://localhost:4200/static/apm/' + VERSION + '/index.html';
    container.id = 'mc-apm-iframe';
    container.frameborder="1";
    container.style.zIndex = 9999;
    container.style.backgroundColor = "transparent";
    container.style.border = "1px";
    container.style.overflowX = "hidden";
    container.style.overflowY = "auto";
    container.style.left = "0px";
    container.style.top = "0px";
    container.style.width = "0px";
    container.style.height = "0px";

    document.body.appendChild(container);

    apmContainer = document.getElementById(container.id).contentWindow;
  }

app.module.ts:

const appRoutes: Routes = [
  {
    path: '',
    redirectTo: 'home-page',
    pathMatch: 'full'
  }
];

/*
 * Main module for the app that boostraps everything.
 */
@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    RouterModule.forRoot(
      appRoutes
    )
  ],
  declarations: [
    RootComponent,
    AppComponent
  ],
  providers: [
    AppGuard,
    WindowRefService,
    EventsService,
    MessageService,
    ApmSharedService,
    {
        provide: HTTP_INTERCEPTORS,
        useClass: AppInterceptor,
        multi: true,
    },
    {provide: APP_BASE_HREF, useValue : '/' }
  ],
  bootstrap: [RootComponent]
})

export class AppModule { }

root.component.ts:

@Component({
    selector: 'app-root',
    template: '<router-outlet></router-outlet>'
})

export class RootComponent {}

app.component.ts:

@Component({
    selector: 'app-comp',
    templateUrl: './app.component.html'
})

export class AppComponent implements AfterViewInit {

  ...... [some stuff] .....

}

标签: javascriptangulariframe

解决方案


推荐阅读