如何从角度2+的服务中获得屏幕大小调整尺寸



首先,这个没有重复的问题需要时间阅读,因为有很多类似的问题,但它们都在@Component装饰器中

我的想法是在服务中捕捉屏幕大小调整,然后通过可观察的对象共享一些css值,但我的服务似乎不起作用(无法捕捉屏幕大小更改事件(。

这是我的代码

import { Injectable, HostListener } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class BreakPointService {
normal: {
background: 'w3-teal',
inputColor: 'w3-light-grey',
css_parent: 'w3-container w3-teal'
};
breakpoint: {
background: 'w3-dark-blue',
inputColor: 'w3-white',
css_parent: 'w3-container w3-light-grey'
};
breakPointValue: number;

css_behaviour = new BehaviorSubject(JSON.stringify(this.breakpoint));
current_css = this.css_behaviour.asObservable();
@HostListener('window:resize', ['$event'])
onResize(event) {
console.log();
this.breakPointValue = window.innerWidth;
console.log(this.breakPointValue);
if (this.breakPointValue > 768) {
console.log(JSON.stringify(this.normal));
this.css_behaviour.next(JSON.stringify(this.normal));
} else {
console.log(JSON.stringify(this.breakpoint));
this.css_behaviour.next(JSON.stringify(this.breakpoint));
}
}
public css() {
if (this.breakPointValue > 768) {
return this.normal;
}
return this.breakpoint;
}
constructor() { }
}

有什么方法可以做到这一点吗?或者这是可以从服务中获得的?

所以我没有在您的OP中看到您正在初始化服务。我不得不在一个应用程序中做这件几乎完全正确的事情。我们注意屏幕大小的变化,这会触发本地存储中一些用户偏好的变化:

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { TableViewTypes, MediaSizes, UserPreferencesDefaults, TableView, getTableViewDefaults } from '../models/user-preferences.model';
import { StorageService } from './storage.service';
@Injectable()
export class UserPreferencesService {
private tableViewSubject = new BehaviorSubject<TableView>(UserPreferencesDefaults.tableView);
tableView$ = this.tableViewSubject.asObservable();
constructor(
private storageService: StorageService
) {}
init() {
this.tableViewSubject.next(
!(window.outerWidth > MediaSizes.sm) ?
getTableViewDefaults(false) :
UserPreferencesDefaults.tableView
);
window.addEventListener('resize', () => {
this.tableViewSubject.next(
!(window.outerWidth > MediaSizes.sm) ?
getTableViewDefaults(false) :
this.storageService.userPreferences.tableView
);
});
}
storeTableView(tableType: TableViewTypes, value: boolean) {
this.storageService.userPreferences = {
...this.storageService.userPreferences,
tableView: {
...this.storageService.userPreferences.tableView,
[tableType]: value
}
};
}
toggleTableView(tableType: TableViewTypes, value?: boolean) {
value = value !== undefined && value !== null ? value : !this.storageService.userPreferences.tableView[tableType];
this.tableViewSubject.next({
...this.storageService.userPreferences.tableView,
[tableType]: value
});
this.storeTableView(tableType, value);
}
}

然后,为了使服务工作,通过将其注入构造函数param 中的app.component.ts来初始化它

constructor(
private userPreferenceService: UserPreferencesService,
) {this.userPreferenceService.init();}

感谢您的回复。

我仍然想在服务中捕捉resise事件,但感谢@ABOS和一些关于组件通信的教程,我得到了使用根组件捕捉scren大小事件的想法,然后向我的服务提供可观察到的更改,这样所有订阅的组件都将获得断点css值

这里不再讨论我的实现

应用程序组件

import { Component, OnInit, HostListener } from '@angular/core';
import { BreakPointService } from './providers/break-point.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'twithashWebApp';
css_parent = '';
breakPointValue: number;
constructor() {
}
ngOnInit() {
BreakPointService.current_css.subscribe(value => {
console.log('value is ' + value);
this.css_parent = JSON.parse(value).css_parent;
});
}
@HostListener('window:resize', ['$event'])
onResize(event) {
console.log();
this.breakPointValue = window.innerWidth;
console.log(this.breakPointValue);
if (this.breakPointValue > 768) {
console.log(JSON.stringify(BreakPointService.normal));
BreakPointService.css_behaviour.next(JSON.stringify(BreakPointService.normal));
} else {
console.log(JSON.stringify(BreakPointService.breakpoint));
BreakPointService.css_behaviour.next(JSON.stringify(BreakPointService.breakpoint));
}
}

}

断点服务

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class BreakPointService {
static normal = {
background: 'w3-teal',
inputColor: 'w3-light-grey',
css_parent: 'w3-container w3-teal'
};
static breakpoint = {
background: 'w3-dark-blue',
inputColor: 'w3-white',
css_parent: 'w3-container w3-light-grey'
};

static css_behaviour = new BehaviorSubject<string>(JSON.stringify(BreakPointService.breakpoint));
static current_css = BreakPointService.css_behaviour.asObservable();

constructor() { }
}

对应模板

<!--The content below is only a placeholder and can be replaced.-->
<div class="{{css_parent}}" style="text-align:center" style="height: 100%">
<app-tweet-list></app-tweet-list>
</div>

您可能需要查看Angular的Flex Layout Package。您可以注入其ObservableMedia服务。这将允许你订阅它,然后监听窗口大小的变化。

import {MediaChange, ObservableMedia} from '@angular/flex-layout';
@Injectable({
providedIn: 'root',
})
export class BreakPointService {
constructor(media: ObservableMedia) {}
resize(){
return this.media.pipe(map(change: MediaChange) => {
//if changes doesn't have the width available on it, access it from the window object
if (window.innerWidth > 768) {       
return JSON.stringify(this.normal);
} else {
return JSON.stringify(this.breakpoint);
}
}));
}
}

无论何时调整窗口大小,都会将媒体更改对象记录到控制台。在您的组件中订阅后。

最新更新