使用 templateUrl 中的条件在移动或桌面模板之间切换 (Angular 7)
Switch between mobile or desktop template using condition in templateUrl (Angular 7)
我想根据屏幕宽度在桌面和移动模板之间切换,以确保我的应用程序具有响应能力。我正在尝试执行以下操作:
@Component({
selector: 'app-root',
templateUrl: "./" + (window.innerWidth < 768) ? "app.component.html" : "app.component.mobile.html",
styleUrls: ['./app.component.css']
})
但是,这不起作用。代替模板加载,字符串 "app.component.html"
出现在屏幕上。
更有趣的是,如果我使用以下内容:
@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
来实现它。但是,我决定不考虑这个想法,因为它不会随着 window 调整大小而切换模板。
我相信你能做到这一点 -
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']
})
然后使用 aot - ng serve --aot 编译您的应用程序。这适用于 angular 的较低版本,我还没有尝试使用 Angular 7,但应该可以。
你这里的方法不对。模板在构建时分配给组件,而不是运行时,并且 Angular 将构建它的所有组件,远早于任何 window 存在的宽度以写出条件。您需要设置逻辑来告诉您的应用程序何时显示哪个组件。
"best practice" (IMO) 在这里,如果你不能做响应式设计(注意:了解你的受众和应用程序的使用方式很重要。我总是尝试先选择移动设备响应式设计,但也认识到这并不总是合适的),是有 2 个组件,并使用路由守卫来强制执行正确的组件。
@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;
}
}
模板如下:
<desktop-app *ngIf="!isMobile"></desktop-app>
<mobile-app *ngIf="isMobile>></mobile-app>
但这不是一种可扩展性很强的方法,并且具有相同的 "duplication" 组件。
如果您的应用程序做很多事情,那么您将需要路由到 /mobile,也许使用 navigator.userAgent,然后将用户推送到那里。
您不能使用旧的 'screen width <= 768',因为例如 iPhone XR 在 5.9" 宽屏幕上的屏幕宽度为 1792 像素,所以实际上重要的是像素密度,而您不能访问。
我想根据屏幕宽度在桌面和移动模板之间切换,以确保我的应用程序具有响应能力。我正在尝试执行以下操作:
@Component({
selector: 'app-root',
templateUrl: "./" + (window.innerWidth < 768) ? "app.component.html" : "app.component.mobile.html",
styleUrls: ['./app.component.css']
})
但是,这不起作用。代替模板加载,字符串 "app.component.html"
出现在屏幕上。
更有趣的是,如果我使用以下内容:
@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
来实现它。但是,我决定不考虑这个想法,因为它不会随着 window 调整大小而切换模板。
我相信你能做到这一点 -
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']
})
然后使用 aot - ng serve --aot 编译您的应用程序。这适用于 angular 的较低版本,我还没有尝试使用 Angular 7,但应该可以。
你这里的方法不对。模板在构建时分配给组件,而不是运行时,并且 Angular 将构建它的所有组件,远早于任何 window 存在的宽度以写出条件。您需要设置逻辑来告诉您的应用程序何时显示哪个组件。
"best practice" (IMO) 在这里,如果你不能做响应式设计(注意:了解你的受众和应用程序的使用方式很重要。我总是尝试先选择移动设备响应式设计,但也认识到这并不总是合适的),是有 2 个组件,并使用路由守卫来强制执行正确的组件。
@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;
}
}
模板如下:
<desktop-app *ngIf="!isMobile"></desktop-app>
<mobile-app *ngIf="isMobile>></mobile-app>
但这不是一种可扩展性很强的方法,并且具有相同的 "duplication" 组件。
如果您的应用程序做很多事情,那么您将需要路由到 /mobile,也许使用 navigator.userAgent,然后将用户推送到那里。
您不能使用旧的 'screen width <= 768',因为例如 iPhone XR 在 5.9" 宽屏幕上的屏幕宽度为 1792 像素,所以实际上重要的是像素密度,而您不能访问。