Skip to content

Instantly share code, notes, and snippets.

@Banttu
Forked from davidmarquis/angular2-if-media-query-directive.ts
Last active February 22, 2023 09:44
Show Gist options
  • Save Banttu/947d9f7dff2fd884b486448a8395e064 to your computer and use it in GitHub Desktop.
Save Banttu/947d9f7dff2fd884b486448a8395e064 to your computer and use it in GitHub Desktop.
Angular: Conditional output from media query using a structural directive
import { Input, Directive, TemplateRef, ViewContainerRef, OnDestroy } from '@angular/core';
/**
* How to use this directive?
*
* ```
* <div *mqIf="'(min-width: 500px)'">
* Div element will exist only when media query matches, and created/destroyed when the viewport size changes.
* </div>
* ```
*/
@Directive({
selector: '[mqIf]'
})
export class MqIfDirective implements OnDestroy {
private prevCondition: boolean = null;
private mql: MediaQueryList;
private mqlListener: (mql: MediaQueryList) => void; // reference kept for cleaning up in ngOnDestroy()
constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef<Object>) {}
/**
* Called whenever the media query input value changes.
*/
@Input()
set mqIf(newMediaQuery: string) {
if (!this.mql) {
this.mql = window.matchMedia(newMediaQuery);
/* Register for future events */
this.mqlListener = (mq) => {
this.onMediaMatchChange(mq.matches);
};
this.mql.addListener(this.mqlListener);
}
this.onMediaMatchChange(this.mql.matches);
}
ngOnDestroy() {
this.mql.removeListener(this.mqlListener);
this.mql = this.mqlListener = null;
}
private onMediaMatchChange(matches: boolean) {
if (matches && !this.prevCondition) {
this.prevCondition = true;
this.viewContainer.createEmbeddedView(this.templateRef);
} else if (!matches && this.prevCondition) {
this.prevCondition = false;
this.viewContainer.clear();
}
}
}
@rubenmarcus
Copy link

Thanks brother, this one is working

@rubenmarcus
Copy link

on resizing the window its adding the binded element ad infinitum

@MALIK-0
Copy link

MALIK-0 commented Apr 13, 2018

@Banttu Hi I'm using your Directive, but found one strange issue. Elements get added when the media condition is true (example: *mqIf="'(min-width: 500px)'"). But once they are added and the viewport changes (in this case shrinks, below 500px) the elements are not removed. Do you have a quick fix for this behaviour? Thanks

Just saw that there is one fork of your repo, which actually fixes this behaviour. @rubenmarcus looks like you are looking for the same thing. Look at the forked version, it fixes the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment