【问题标题】:How to use a GWT application in Angular 7 application as a component?如何在 Angular 7 应用程序中将 GWT 应用程序用作组件?
【发布时间】:2019-04-11 06:09:34
【问题描述】:

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

这是我尝试过的:

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

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

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

  • 我知道在构建 Angular 项目时会创建 main.js 文件,该文件包含所有组件的已编译 JS 代码,包括它们的路由。所以,我也想过把GWT的主要nocache.js文件转成TS文件,但是导致语法错误很多,所以忽略了这个过程。

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

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

【问题讨论】:

    标签: angular gwt angular7 angular-routing smartgwt


    【解决方案1】:

    我正在添加另一个答案来解决第一个答案的评论中提到的问题。问题是即使组件被RouteReuseStrategy 保持活动状态,组件内的iframe 仍然会重新加载。这可能是因为 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

    【讨论】:

    • 感谢您的回答。尽管通过使用与您相同的代码,iframe 在页面中显示了两次。因此,我可以通过在 html 中的 语句中使用“*ngIf”而不是“[hidden]”来实现预期的目标,以实现“出口>"
    • 通过使用 RoutingReuseStrategy,我无法读取我的根组件中的查询参数,而我之前能够成功地做到这一点。那么,您能建议在这种情况下该怎么做吗?
    • 对于此解决方案,您不需要RouteReuseStrategy。我已经在示例中删除了它。使用ActivatedRoute 这里是一个sample from the documentation 关于如何读取参数。如果这不起作用,您还可以更改为我使用NavigationEnd 事件的ActivationEnd 事件。您还可以在snapshot property 中获得有关参数的信息。
    【解决方案2】:

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

    默认情况下,Angular 路由会在您每次转到另一个组件时销毁该组件,并在您返回时再次创建它。这就是为什么它每次都会重新加载。 您需要做的是实现一个自定义的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”在您离开时不会被破坏。

    【讨论】:

    • 在 GWT 组件中,我将 GWT 应用程序放在 iFrame 中。尽管通过使用 RoutingReuseStrategy,ngOnDestroy 没有被调用,但是在该页面中来回导航时,应用程序的 js 和 css 文件一次又一次地重新加载。你能就此提出一些建议吗?
    • 我试过iframe,正如你所说,这是一个问题。我发布了另一个带有解决方法的答案。
    猜你喜欢
    • 2019-08-16
    • 1970-01-01
    • 2019-10-02
    • 2020-04-24
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    相关资源
    最近更新 更多