【问题标题】:Different views for Desktop and mobile Angular桌面和移动 Angular 的不同视图
【发布时间】:2017-11-29 10:48:30
【问题描述】:

在我正在开发的应用程序中,它需要桌面和移动完全两种不同的视图。不可能使用 CSS 作为内容完全不同。

我做了什么?

我在 Routing file 中使用代码 const isMobile = window.innerWidth < 768;

检查了它是否是桌面/移动设备

在路径组件中:component: isMobile ? MobileComponent : DesktopComponent

这在开发环境中运行良好。但是,虽然生产构建失败了ng serve --prod(显然是 Angular 5)

问题:

完全没有错误,根据isMobile true/false 它应该加载MobileComponent/DesktopComponent。但即使 isMobile 为真/假也不会加载

始终在桌面和移动设备中加载 MobileComponent。虽然isMobile 值计算正确,true 用于Mobilefalse 用于Desktop

我认为原因是路由在发送到客户端之前已经编译。

尝试了解决方法但不起作用:

使用 if..else 条件,同时计算 isMobile 并在路由文件中给出该变量(组件)而不是三元运算

任何方式:

有什么方法可以实现相同的功能吗?

提前致谢

【问题讨论】:

  • AOT 中的错误是什么?
  • @Dhyey 完全没有错误,即使 isMobile 为真/假,也只是加载MobileComponent
  • 你试过“window.screen.width”
  • @shanths isMobile 计算正确,三元运算无法正常工作 component: isMobile ? MobileComponent : DesktopComponent 总是返回 MobileComponent
  • 但对我来说它在生产中工作demo link

标签: javascript angular mobile


【解决方案1】:

正如我在问题评论部分所说,路由守卫将是一个很好的解决方案。

MobileGuard 看起来像这样:

export class MobileGuard implements CanActivate {
    constructor(private _router: Router, private _mobileService: MobileService) {}

    canActivate(): boolean {
        const isMobile = this._mobileService.isMobile();
        if(!isMobile) {
            this._router.navigate(['/desktop']);
        }
        return isMobile;
    }
}

DesktopGuard 也是如此。

尝试访问任何路由的用户将被重定向到正确的路由。

Here is a running example with this suggested solution.

And here is the stackblitz editable version.

【讨论】:

  • 感谢您的解决方案。我试试看
【解决方案2】:

不要使用 canActivate 或路由守卫,因为它们需要用于身份验证等。

新方法:

{
    path: 'your-path',
    loadChildren: () => {
      if(window.innerWidth > 768 ) {
        return import('./your-desktop.module').then(m => m.YourDesktopModule)
      } else {
        return import('./your-mobile.module').then(m => m.YourMobileModule)
      }
    }
}

【讨论】:

    【解决方案3】:

    像这样直接修改路由 -

    const routes: Routes = [{
      path: '',
      component:  window.screen.width > 767 ? WelcomeDesktopComponent : WelcomeMobileComponent
    }];
    
    

    【讨论】:

      【解决方案4】:

      我同意 @CarbonDry 的观点,即在 RoutingModule 中使用逻辑是最好的方法。 但是我认为使用窗口大小是检测设备类型的一种不好的方法。当然,这取决于用例 - 如果您只是需要为小屏幕显示不同的 UI,window.innerWidth 就可以了。如果您想为手机提供单独的功能,那可能还不够。

      您可以通过多种方式检查设备类型,例如,您可以使用navigator.orientation === undefined 来检查设备是否为桌面设备(因为桌面不支持navigator.orientation

      最后,您始终可以使用UserAgent 检测。为此,请参阅此线程https://stackoverflow.com/a/13819253/8775880

      所以最后,你的代码可能是这样的

      const isDesktop(): boolean => {
         return navigator.orientation === undefined;
      }
      
      {
          path: 'path',
          loadChildren: () => {
            if(isDesktop())
              return import('./desktop.module').then((m) => m.DesktopModule);
            return import('./mobile.module').then((m) => m.MobileModule);
          }
      }
      

      编辑 但是请记住,第一次加载路径时,loadChildren 只会运行一次。因此,您可能需要考虑简单地检查屏幕尺寸。假设768px 适用于手机上的纵向,但如果我以横向模式打开网站怎么办?在某些情况下,即使是横向模式也需要移动 UI。但是如果你只检查客户端宽度,你会得到桌面版本。

      【讨论】:

        猜你喜欢
        • 2015-12-03
        • 1970-01-01
        • 2019-07-30
        • 1970-01-01
        • 2013-04-24
        • 2013-10-28
        • 2018-10-07
        • 2014-06-25
        • 2020-10-22
        相关资源
        最近更新 更多