Warm tip: This article is reproduced from serverfault.com, please click

Angular 2: Detect changes in browser width and update model

发布于 2016-09-17 18:45:39

In my Angular 2 app, I change styles based on browser window width. Here is a sample (SCSS):

.content{
    /*styles for narrow screens*/
    @media (max-width: 750px){
        background-color:beige;
    }
    /*styles for medium screens*/
    @media (min-width: 751px) and (max-width: 1200px) {
        background-color:red;
    }
    /*styles for wide screens*/
    @media (min-width: 1201px) {
        background-color:brown;
    }   
}

This makes my UI responsive. I'd like my Angular components to know which width interval is current:

/* Returns which of the CSS width intervals is current*/
getWidthRange(){
    let pixelWidth = ...; //what goes here?

    if(pixelWidth < 251) return "small";
    if(pixelWidth < 451) return "medium";
    return "large"; 
}   

A component would call this function and adjust its behavior based on width. For instance, the template below will show more content on wider screens:

<div>
    {{getWidthRange()==='small'? shortText : longText}}
</div>

Even better, I would setup an Observable that emits when the browser transitions from one range to the next:

widthRangeChanges = Observable.create( observer => 
    {       
        // ? how to detect when width changes
        let oldRange = '...';
        let newRange = '...';
        if(newRange!==oldRange) observer.next(newRange);
    }
).share(); //all subscribers share same output channel

The component could then subscribe to widthRangeChanges and update model values when a new range is received. How can I get hold of this info in Angular 2?

Angular 2 rc-6, typescript 2.0.2, rxjs 5 beta 11

Questioner
BeetleJuice
Viewed
0
yurzui 2016-09-18 03:03:49

You can use fromEvent operator of RxJS:

 const $resizeEvent = Observable.fromEvent(window, 'resize')
   .map(() => {
     return document.documentElement.clientWidth;
   })
   .debounceTime(200)

   $resizeEvent.subscribe(data => {
     this.width = data;
   });

Plunker Example