Angular 使用templateUrl(7)中的条件在移动或桌面模板之间切换

Angular 使用templateUrl(7)中的条件在移动或桌面模板之间切换,angular,responsive-design,angular7,Angular,Responsive Design,Angular7,我想根据屏幕宽度在桌面和移动模板之间切换,以确保我的应用程序响应迅速。我正在努力做到以下几点: @Component({ selector: 'app-root', templateUrl: "./" + (window.innerWidth < 768) ? "app.component.html" : "app.component.mobile.html", styleUrls: ['./app.component.css'] }) @Component({

我想根据屏幕宽度在桌面和移动模板之间切换,以确保我的应用程序响应迅速。我正在努力做到以下几点:

@Component({
    selector: 'app-root',
    templateUrl: "./" + (window.innerWidth < 768) ? "app.component.html" : "app.component.mobile.html",
    styleUrls: ['./app.component.css']
})
@Component({
    selector: 'app-root',
    templateUrl: "./" + (false) ? "app.component.html" : "app.component.mobile.html",
    styleUrls: ['./app.component.css']
})
页面仍然只显示字符串“app.component.html”

不支持使用条件语句作为
@Component
装饰器中
templateUrl
字段的值吗

如果没有,我可以使用什么替代解决方案来实现这一仍然是模块化的、遵循最佳实践的响应级别


更新:我通过使用
ng-serve--aot
而不仅仅是
ng-serve
实现了这一点。但是,我决定不使用这个想法,因为它不会随着窗口大小的改变而切换模板。

我相信你可以做到这一点-

export function getTemplateUrl() {
  if (window.innerWidth < 768)
    return "app.component.html";
  else 
    return "app.component.mobile.html";
}

@Component({
  selector: 'app-root',
  templateUrl: getTemplateUrl(),
  styleUrls:['./app.component.css']
})
导出函数getTemplateUrl(){
如果(窗内宽度<768)
返回“app.component.html”;
其他的
返回“app.component.mobile.html”;
}
@组成部分({
选择器:'应用程序根',
templateUrl:getTemplateUrl(),
样式URL:['./app.component.css']
})

然后使用aot-ng serve--aot编译应用程序。这适用于angular的较低版本,我还没有尝试过angular 7,但应该可以

您在这里的方法已关闭。模板是在构建时分配给组件的,而不是在运行时,Angular将构建它的所有组件,远远早于任何窗口存在的宽度来写条件关闭。你需要设置逻辑来告诉你的应用程序何时显示哪个组件

@Injectable()
export class MobileGuard implements CanActivate {

  constructor(
    private router: Router
  ) { }

  canActivate() {

    if (window.innerWidth >= 768) {
      this.router.navigate(['/']);
      return false;
    }

    return true;
  }
}

@Injectable()
export class DesktopGuard implements CanActivate {

  constructor(
    private router: Router
  ) { }

  canActivate() {

    if (window.innerWidth < 768) {
      this.router.navigate(['/m/']);
      return false;
    }

    return true;
  }
}
这里的“最佳实践”(IMO),如果你不能进行响应式设计(注意:了解你的受众和应用程序的使用方式很重要。我总是尝试选择移动优先响应式设计,但也认识到这并不总是合适的),就是有两个组件,并使用路由防护来强制执行正确的组件

@Injectable()
export class MobileGuard implements CanActivate {

  constructor(
    private router: Router
  ) { }

  canActivate() {

    if (window.innerWidth >= 768) {
      this.router.navigate(['/']);
      return false;
    }

    return true;
  }
}

@Injectable()
export class DesktopGuard implements CanActivate {

  constructor(
    private router: Router
  ) { }

  canActivate() {

    if (window.innerWidth < 768) {
      this.router.navigate(['/m/']);
      return false;
    }

    return true;
  }
}
至于组件本身,您的移动组件只是扩展了非移动组件,并具有不同的关联模板/样式

另一种方法是这样做:

const routes: Routes = [
  {
    path: '',
    component: AppComponent,
    canActivate: [DesktopGuard],
    children: [... desktop routes ...]
  },
  {
    path: 'm',
    component: MobileAppComponent,
    canActivate: [MobileGuard],
    children: [... mobile routes ...]
  }
]
export class WrapperAppComponent {
    isMobile: boolean;

    constructor() {
      this.isMobile = window.innerWidth < 768;
    }
}
导出类包装器AppComponent{
isMobile:布尔;
构造函数(){
this.isMobile=window.innerWidth<768;
}
}
使用类似以下的模板:

<desktop-app *ngIf="!isMobile"></desktop-app>
<mobile-app *ngIf="isMobile>></mobile-app>


如果你的应用程序做了很多事情,那么你需要路由到a/mobile,可能需要使用navigator.userAgent,并将用户推到那里


您不能使用旧的“屏幕宽度”是否确实要()调用函数?当我进行更改并运行
ng serve--aot时,我遇到了以下错误:
decorators中不支持“AppComponent”函数调用的模板编译过程中出错,但调用了“getTemplateUrl”。
不确定这将如何工作;阅读templateURL在组件构建时必须是静态的地方尝试将配置对象声明为变量并将其记录到控制台,然后将其传递给装饰器。我想知道你的脚本是不是不新鲜。你也可以粘贴两个html文件的内容吗?使用这种方法,这是否意味着我需要声明两倍的路由?因此,如果我有一条
/user
路线,我需要定义一条
/m/user
路线,并为每一条路线设置防护?因此,如果你的网站有一个移动版本,提供相同的功能(或者可能稍微减少),那么响应式设计可能是更好的选择?这里的想法是,如果你有一个网站适合于移动版本和桌面版本,那么移动版本应该缩小或足够不同,以保证不使用响应性设计(即显著不同的功能子集)。因此,您将拥有一组移动功能和路由,以及一组桌面功能和路由。但是防护只在每个路由器树的顶层进行。已经有了一些响应性设计,但是对于我想要的布局,我需要在媒体查询和脚本方面做一些繁重的工作,而我不希望这样做。不过我喜欢这个解决方案,所以我会尝试一下。我对桌面和移动设备使用相同的路由,因此在
m
children
属性中,我会将所有路由放在这两个位置吗?移动路由将指向移动组件,桌面路由将指向桌面组件。