Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: Detect changes in browser width and update model

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

like image 846
BeetleJuice Avatar asked Dec 03 '22 14:12

BeetleJuice


2 Answers

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

like image 53
yurzui Avatar answered Dec 15 '22 00:12

yurzui


Template

<div (window:resize)="onResize($event)"></div>

export class AppComponent {            
      onResize(event) {
        console.log(event);
        console.log("width:" + event.target.innerWidth);
        console.log("height:" + event.target.innerHeight);

        this.pixelWidth = event.target.innerWidth;
      }

      getWidthRange(){
         if(this.pixelWidth < 251) return "small";
         if(this.pixelWidth < 451) return "medium";
         return "large"; 
      }
}
like image 35
Nikhil Shah Avatar answered Dec 14 '22 23:12

Nikhil Shah