Как получить размер изменения размера экрана от сервиса в angular 2+? - PullRequest
0 голосов
/ 09 декабря 2018

Сначала это не дублируется, требуется время для чтения, потому что есть много похожих вопросов, но они находятся в декораторе @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() { }
}

Есть ли способ сделать это или это невозможно из службы?

Ответы [ 3 ]

0 голосов
/ 09 декабря 2018

Так что я не видел в вашем ОП, где вы инициализируете сервис.Я должен был сделать это почти точно в одном приложении.Мы наблюдаем за изменениями размера экрана, которые вызывают изменения в некоторых пользовательских настройках в локальном хранилище:

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);
    }

}

Затем для того, чтобы служба работала, ее инициализируют, внедрив ее в app.component.ts в конструкторе.парам

constructor(
    private userPreferenceService: UserPreferencesService,
) {this.userPreferenceService.init();}
0 голосов
/ 09 декабря 2018

Спасибо за все ответы.

Я все еще хочу перехватить событие resise в сервисе, но благодаря @ABOS и некоторым учебникам по взаимодействию компонентов я получил идею использовать корневой компонент для отлова screnзатем событие size, чтобы прокормить мой сервис изменениями, которые можно наблюдать; таким образом, все подписанные компоненты получат значения css точки останова

. Больше не нужно говорить о моей реализации

app.component

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>
0 голосов
/ 09 декабря 2018

Возможно, вы захотите проверить пакет Angular Flex-Layout.Вы можете добавить сервис 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);
        }
      }));
     }
   }

будет регистрировать объект смены носителя на вашей консоли всякий раз, когда вы изменяете размер окна.После того, как вы подписались на него в вашем компоненте.

...