Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Preston Lamb
Preston Lamb

Posted on • Originally published atprestonlamb.com on

     

Angular CDK's BreakpointObserver

tldr;

Sometimes we need to know the width of the browser window in our component’s class file. You could have a@HostListener in a component for the window’s resize event, but you’d have to maintain the service, write tests to make sure it was working properly, handle observables correctly so there aren’t memory leaks, etc. TheAngular CDK’sLayoutModule has aBreakpointObserver class that you can inject into a component, provide a breakpoint (or breakpoints) that you want to watch for, and it will emit each time you cross the threshold of a breakpoint (i.e. if I want to know when the screen is smaller than 700px, it will emit a value when I cross under 700px, and then again when I cross back over 700px).

The Problems This Solves

First off, I’ve been using Angular daily for almost 4 years now, since before the first Angular 2 Beta release, and this is the first time I’ve needed this functionality. So you might be wondering when or why you would ever need this. But there are times when it is very useful, which is why the class exists in the@angular/cdk library.

I ended up needing this functionality because I am using thengx-gauge library, and one of the options to set in the library is the thickness of the line. You pass it in as an input to the component from the library, and it draws the chart at that thickness. In addition, you pass in asize attribute that sets the height and width. Because of that, I couldn’t change the thickness or the height and width of the chart using CSS media queries. I was left with two options: 1) have two charts on the page, one for bigger screens and one for smaller screens or 2) change the values of those inputs depending on screen size. I chose the latter, because I didn’t want to have to update two charts every time I made a change.

The solution (we’ll go over that in a minute) worked great for me, but I will say that I think the first thing you should try is using CSS media queries before doing this. It would be unnecessary, for example, to keep track of the screen width in your component’s class file, and then apply a class to an HTML element (withngClass, for example) based on the screen width.Maybe there is a scenario where that is what you need to do, but generally I think you’ll be better off just using CSS media queries to style your components. Having said that, however, if you feel this is the best option for your component, go ahead and do it! I don’t want you to feel bad about usingBreakpointObserver.

The Solution

The solution to this problem is pretty simple, thanks to the Angular CDK. The first step is to install the CDK to your project:

npm i @angular/cdk
Enter fullscreen modeExit fullscreen mode

Next, import theLayoutModule from@angular/cdk/layout to your module. For example, like this in theapp.module.ts file:

import{LayoutModule}from'@angular/cdk/layout';@NgModule({imports:[...,LayoutModule,...]})exportclassAppModule{}
Enter fullscreen modeExit fullscreen mode

After importing theLayoutModule, inject theBreakpointObserver into your component like any other service you would use:

import{BreakpointObserver}from'@angular/cdk/layout';exportclassMyComponent{constructor(privateobserver:BreakpointObserver){}}
Enter fullscreen modeExit fullscreen mode

Alright, now everything is set up and ready to use. There’s one more thing to figure out, though, before using the service, and that is what break points you want to be notified of. For example, if your site is using Bootstrap and you want to know when you are on the small screen or lower, you would use ‘(max-width: 767px)’. The value you put in the strings is the part of your CSS media query parentheses, parentheses included. You can provide a single string value, or an array of strings.

Once you’ve determined your breakpoints, you have two options to use from theBreakpointObserver. The first one is theisMatched method. It simply evaluates the breakpoints you provided and tells you if the values are matched or not. If you pass in an array to this method, all conditions have to be met for the function to return true.

constmatched=this.observer.isMatched('(max-width: 700px)');// ORconstmatched=this.observer.isMatched(['(max-width: 700px)','(min-width: 500px)']);
Enter fullscreen modeExit fullscreen mode

TheisMatched function works great if you only need to check the first time the page is loaded, or if you only want to check by calling that function occasionally. If you want to be constantly alerted of the matching of your breakpoints, you can use theobserve method. Theobserve method allows you to subscribe and get an update every time the window passes one of the widths that you’ve defined. If you’ve only defined one width to the function, then it will emit a value each time you go above or below that single width. If you provided an array of widths, then each time you cross over the threshold of one of the widths in the array, a value is emitted.

this.observer.observe('(max-width: 700px)').subscribe(result=>{console.log(this.result);// Do something with the result});
Enter fullscreen modeExit fullscreen mode

Theresult that’s outputted here looks like this:

{"matches":true|false,"breakpoints":{"(max-width: 350px)":true|false,"(max-width: 450px)":true|false}}
Enter fullscreen modeExit fullscreen mode

Thematches attribute is true if any conditions are met. You can also check for individual breakpoints to see if they have been met if you need.

This function is great if you need to change some layout on the page each time the browser width crosses a certain value. Like I mentioned in my example above, I needed to change the size of a chart and the thickness of the chart depending on the browser width, and since it could be different on landscape vs portrait, I decided to subscribe to the observer method and change it each time it emitted a value.

The last thing to know about theBreakpointObserver is that the CDK provides some built in breakpoints that you can use if you want. They are based on Google’s Material Design specification, and the values are:

  • Handset
  • Tablet
  • Web
  • HandsetPortrait
  • TabletPortrait
  • WebPortrait
  • HandsetLandscape
  • TabletLandscape
  • WebLandscape

You can use them by importingBreakpoints from the CDK’slayout folder:

import{Breakpoints}from'@angular/cdk/layout';
Enter fullscreen modeExit fullscreen mode

You can then use a breakpoint, likeBreakpoint.Handset, in theobserve orisMatched functions. They can be used as the only input, or added to the array that is passed in to those functions. You can also mix your own breakpoints with the those built-in ones..

Conclusion

As I said before, you may never use this class or need this functionality. It doesn’t come up very often, but it’s nice to know that this is there and you can reach for it when you do need it. One thing that I want to look into is to see if you could use this function to swap out the template file that the Angular component is using. Again, that would be a rare condition, but you might need it to swap out the content for a mobile experience if it is very different from the desktop experience. I don’t know if you could exactly do that, but you could at least show and hide child components based on the results of theBreakpointObserver.

If you have used this before, make sure to let me know on Twitter or via email how you’ve used it. If you haven’t yet, but need to in the future, also let me know! I like to hear about how other developers use things like this so I can learn more!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Preston Lamb is a full stack JavaScript developer, Angular GDE, ngChampion writer for the ng-conf blog, & co-organizer of the Angular Community Meetup.
  • Location
    Roy, UT
  • Education
    BS in Computer Science from Utah State University
  • Work
    Software Developer at MotivHealth
  • Joined

More fromPreston Lamb

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp