我有 3 种完全不同的设计,适用于移动设备、平板电脑和台式机。我决定将 Angular Signals 与媒体查询结合使用来了解 Angular 应用程序的状态。错误在于,尽管 Angular 正确识别出我们处于特定模式(例如平板电脑模式),但某些类并未在
NgClass
指令中呈现。 isTablet()
在组件 TS 和模板 HTML 中都有效,但是当 NgClass
为 true 时,isTablet()
不会呈现适当的类。所有媒体查询工作都是通过这个 Media Query Angular Tutorial 完成的。为了方便起见,以下提供服务。
媒体查询服务:
export class MediaQueryService {
// important breakpoints that we care about
private readonly BREAKPOINTS = {
lg: '1200px',
md: '768px',
sm: '0px',
}
private activeMediaQueries: {[key: string]: Observable<boolean>} = {}
mediaQuery(type: 'min' | 'max', breakPoint: keyof typeof this.BREAKPOINTS): Observable<boolean> {
const mediaId = `${type}-${breakPoint}`;
if(mediaId in this.activeMediaQueries) {
return this.activeMediaQueries[mediaId]
}
const mqText = `(${type}-width: ${this.BREAKPOINTS[breakPoint]})`;
const mediaQuery = window.matchMedia(mqText); // this returns something called the MediaQueryList.
const dynamicMediaQuery = fromEvent<MediaQueryList>(mediaQuery, 'change').pipe(
startWith(mediaQuery), // sync emit all values passed to the operator
map((query: MediaQueryList)=> query.matches)
)
this.activeMediaQueries[mediaId] = dynamicMediaQuery;
return dynamicMediaQuery;
}
}
我在组件中的实现方式如下:
export class BillsComponent {
#mediaQueryService = inject(MediaQueryService)
isMobile = toSignal(this.#mediaQueryService.mediaQuery('max', 'md'));
isDesktop = toSignal(this.#mediaQueryService.mediaQuery('min', 'lg'));
isTablet = computed(() => (!this.isMobile() && !this.isDesktop()))
}
但是,
NgClass
指令中的特定类不起作用。
<!--
'container br bg-white' are not implemented even when on mobile or tablet (they exist.)
-->
<div [ngClass]="{'container br bg-white p-300 mt-300': isMobile() || isTablet(), 'container br bg-white p-400': isDesktop()}">
<app-header [title]="'Recurring Bills'">See Details</app-header>
<div class="flex mt-400">
<app-bill [amount]="'$190.00'" [title]="'Paid Bills'" [color]="'#277C78'"></app-bill>
<app-bill [amount]="'$194.98'" [title]="'Total Upcoming'" [color]="'#F2CDAC'"></app-bill>
<app-bill [amount]="'$59.98'" [title]="'Due Soon'" [color]="'#82C9D7'"></app-bill>
</div>
</div>
<div class="text-preset-1">
<!-- This is correctly rendered when we adjust the view -->
<p>isMobile or Tablet is {{isMobile() || isTablet()}}</p>
<p>isDesktop is {{isDesktop()}}</p>
</div>
我的猜测是关于变化检测的事情?
如有任何帮助,我们将不胜感激。
您可以尝试在
[ngClass]
中的条件周围添加括号:
<div [ngClass]="{'container br bg-white p-300 mt-300': (isMobile() || isTablet()), 'container br bg-white p-400': isDesktop()}">
<app-header [title]="'Recurring Bills'">See Details</app-header>
<div class="flex mt-400">
<app-bill [amount]="'$190.00'" [title]="'Paid Bills'" [color]="'#277C78'"></app-bill>
<app-bill [amount]="'$194.98'" [title]="'Total Upcoming'" [color]="'#F2CDAC'"></app-bill>
<app-bill [amount]="'$59.98'" [title]="'Due Soon'" [color]="'#82C9D7'"></app-bill>
</div>
</div>