如何在Angular 7应用程序中使用GWT应用程序作为组件?

如何在Angular 7应用程序中使用GWT应用程序作为组件?,angular,gwt,angular7,angular-routing,smartgwt,Angular,Gwt,Angular7,Angular Routing,Smartgwt,我有一个Angular 7应用程序,我想使用一个单页GWT应用程序作为组件。将该GWT应用程序用作组件的原因是,我不希望我的GWT应用程序在使用角度路由导航到该应用程序(或页面)时一次又一次地重新加载 以下是我尝试过的: 首先,我将GWT项目的编译二进制文件放在Angular应用程序的assets文件夹中。然后我将所有内容放在Angular应用程序的component.html文件中的index.html标记下。然后添加了一个按钮,并在其点击事件上应用了路由器导航,这样点击该按钮将导航到我的A

我有一个Angular 7应用程序,我想使用一个单页GWT应用程序作为组件。将该GWT应用程序用作组件的原因是,我不希望我的GWT应用程序在使用角度路由导航到该应用程序(或页面)时一次又一次地重新加载

以下是我尝试过的:

  • 首先,我将GWT项目的编译二进制文件放在Angular应用程序的assets文件夹中。然后我将所有内容放在Angular应用程序的component.html文件中的index.html标记下。然后添加了一个按钮,并在其点击事件上应用了路由器导航,这样点击该按钮将导航到我的Angular应用程序的组件页面

  • 我将GWT应用程序嵌入到角度组件的iFrame中。但我观察到,当通过路由导航到该页面时,每当我来回导航到该页面以及使用路由导航到另一个角度页面时,它都会一次又一次地重新加载

  • 我还在angular.json文件的scripts参数中添加了GWT应用程序所需的所有javascript文件的路径,并在tsconfig.json中将allowJs参数修改为true

  • 我知道在构建Angular项目时,会创建main.js文件,其中包含所有组件的编译js代码,包括它们的路由。因此,我还考虑将GWT的主要nocache.js文件转换为TS文件,但这会导致很多语法错误,因此我忽略了这个过程

现在我的知识有限,除了上面指定的解决方案之外,我想不出任何解决方案,我真的陷入了这种情况,无法继续我的项目


那么,有谁能帮我找到解决方案吗?我也不确定是否可以这样做。

如果我理解正确,您希望在导航到其他路线时保持角度组件(页面)处于活动状态

默认情况下,角度布线会在每次转到另一个零部件时销毁零部件,并在返回零部件时再次创建零部件。这就是为什么它会再次加载。 您需要做的是实现一个定制,使您的组件保持活动状态

下面是一个非常简单的实现,它假设您的GWT应用程序组件具有路由“GWT”

export class GwtRouteReuseStrategy extends RouteReuseStrategy {
  private cache: {[key: string]: DetachedRouteHandle} = {};

  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.url.join('/') === 'gwt';
  }

  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    this.cache[route.url.join('/')] = handle;
  }

  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return this.cache[route.url.join('/')] != null;
  }

  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    return this.cache[route.url.join('/')];
  }

  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.url.join('/') === 'gwt';
  }
}
您需要在应用程序模块提供程序中提供策略,以便路由器使用该策略

@NgModule({
  …,
  providers: [
    { provide: RouteReuseStrategy, useClass: GwtRouteReuseStrategy}
  ],
})
export class AppModule {
}

这里还有一个示例链接,您可以在其中看到它的工作情况。打开控制台,查看“GwtComponent”在您导航到其他路线时不会被破坏。

如果我理解正确,您希望在导航到其他路线时保持角度组件(页面)处于活动状态

默认情况下,角度布线会在每次转到另一个零部件时销毁零部件,并在返回零部件时再次创建零部件。这就是为什么它会再次加载。 您需要做的是实现一个定制,使您的组件保持活动状态

下面是一个非常简单的实现,它假设您的GWT应用程序组件具有路由“GWT”

export class GwtRouteReuseStrategy extends RouteReuseStrategy {
  private cache: {[key: string]: DetachedRouteHandle} = {};

  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.url.join('/') === 'gwt';
  }

  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    this.cache[route.url.join('/')] = handle;
  }

  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return this.cache[route.url.join('/')] != null;
  }

  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    return this.cache[route.url.join('/')];
  }

  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.url.join('/') === 'gwt';
  }
}
您需要在应用程序模块提供程序中提供策略,以便路由器使用该策略

@NgModule({
  …,
  providers: [
    { provide: RouteReuseStrategy, useClass: GwtRouteReuseStrategy}
  ],
})
export class AppModule {
}

这里还有一个示例链接,您可以在其中看到它的工作情况。打开控制台,查看导航离开时“GwtComponent”不会被破坏。

我正在添加另一个答案,以解决第一个答案评论中提到的问题。问题是,组件内部的
iframe
仍然会被重新加载,即使该组件被。这可能是因为Angular将其从页面DOM中分离,然后重新连接

一个变通解决方案是将带有
iframe
的组件始终保持在主应用程序组件中,并在导航到另一个页面时将其隐藏。然后,如果导航到要显示它的路线,请再次显示它。您可以使用

下面是实现此变通方法的示例应用程序组件。
gwt
组件是带有iFrame的组件

模板:

<h2><a routerLink="/main">Main</a></h2>
<h2><a routerLink="/gwt">Gwt</a></h2>
<gwt [hidden]="!gwtVisible"></gwt>
<router-outlet [hidden]="gwtVisible"></router-outlet>
从代码中可以看出,当您导航到
/gwt
路由时,应用程序组件会隐藏主要内容,并显示
gwt
组件,否则它会将其隐藏,并通常从
路由器出口显示其他内容

在routes中,我定义它导航到一个空组件,只是为了为route
/gwt
提供一些内容

const routes: Routes = [
  { path: '', redirectTo: 'main', pathMatch: 'full' },
  { path: 'main', component: MainComponent },
  { path: 'gwt', component: EmptyComponent }
];

我还创建了一个工作示例。

我正在添加另一个答案,以解决第一个答案评论中提到的问题。问题是,组件内部的
iframe
仍然会被重新加载,即使该组件被。这可能是因为Angular将其从页面DOM中分离,然后重新连接

一个变通解决方案是将带有
iframe
的组件始终保持在主应用程序组件中,并在导航到另一个页面时将其隐藏。然后,如果导航到要显示它的路线,请再次显示它。您可以使用

下面是实现此变通方法的示例应用程序组件。
gwt
组件是带有iFrame的组件

模板:

<h2><a routerLink="/main">Main</a></h2>
<h2><a routerLink="/gwt">Gwt</a></h2>
<gwt [hidden]="!gwtVisible"></gwt>
<router-outlet [hidden]="gwtVisible"></router-outlet>
从代码中可以看出,当您导航到
/gwt
路由时,应用程序组件会隐藏主要内容,并显示
gwt
组件,否则它会将其隐藏,并通常从
路由器出口显示其他内容

在routes中,我定义它导航到一个空组件,只是为了为route
/gwt
提供一些内容

const routes: Routes = [
  { path: '', redirectTo: 'main', pathMatch: 'full' },
  { path: 'main', component: MainComponent },
  { path: 'gwt', component: EmptyComponent }
];

在GWT组件中,我将我的GWT应用程序放在一个iFrame中。虽然通过使用RoutingReuseStragey,ngOnDestroy没有被调用,但是