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

问题描述 投票:0回答:2

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

这是我试过的:

  • 首先,我将该GWT项目的已编译二进制文件放在我的Angular应用程序的assets文件夹中。然后我将所有内容放在我的Angular应用程序的component.html文件中的index.html标记下。然后在其点击事件上添加了一个按钮并应用路由器导航,以便单击该按钮将导航到我的Angular应用程序的组件页面。
  • 我将GWT应用程序嵌入到Angular组件的iFrame中。但我观察到,当通过路由导航到该页面时,每当我来回导航到该页面并使用路由到另一个Angular页面时,它就会一次又一次地重新加载。
  • 我还在angular.json文件的scripts参数中添加了GWT app所需的所有javascript文件的路径,并在tsconfig.json中将allowJs参数修改为true。
  • 我知道在构建Angular项目时会创建main.js文件,该文件包含所有组件(包括其路由)的已编译JS代码。所以,我还想过将GWT的主要nocache.js文件转换为TS文件,但是它导致了很多语法错误,所以我忽略了这个过程。

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

那么,任何人都可以帮我找到它的解决方案吗?我也不确定是否可以这样做。

angular gwt angular7 angular-routing smartgwt
2个回答
1
投票

我正在添加另一个答案来解决第一个答案的评论中提到的问题。问题是组件内部的iframe仍然会重新加载,即使组件由RouteReuseStrategy保持活着。这可能是因为Angular将其从页面DOM中分离出来然后重新附加它。

解决方案的一个方法是使iframe中的组件始终在主应用程序组件中保持活动状态,并在导航到另一个页面时隐藏它。如果您导航到要显示它的路线,则再次显示它。你可以使用Router events来做到这一点。

以下是实现此变通方法的示例应用程序组件。 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>

代码:

export class AppComponent  {
  gwtVisible = false;

  constructor(router: Router) {
    router.events.subscribe((routerEvent) => {
      if (routerEvent instanceof NavigationEnd) {
        this.gwtVisible = routerEvent.url === '/gwt';
      }
    });
  }
}

从代码中可以看出,当您导航到/gwt路径并显示gwt组件时,应用程序组件会隐藏主要内容,否则它会隐藏它并通常从router-outlet显示其他内容。

在我定义的路线中,它导航到一个空组件,只是为路线/gwt提供了一些东西。

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

我还创建了一个带有工作样本的StackBlitz


1
投票

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

默认情况下,角度路由会在每次转到另一个组件时销毁该组件,并在您返回时再次创建它。这就是它每次都加载的原因。你需要做的是实现一个自定义的RouteReuseStrategy,让你的组件保持活力。

这是一个非常简单的实现,假设您的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 {
}

这里还有一个StackBlitz样本的链接,你可以看到它的工作原理。打开控制台,看看当你离开时'GwtComponent'不会被破坏。

© www.soinside.com 2019 - 2024. All rights reserved.