comment faire réactif composants dans Angular2

Je suis à gué sur mon chemin Angular2. Mon objectif est de créer un réactif application qui charge les différents composants en réponse à différents media-queries pour appareil largeurs. Mon exemple de travail a un MatchMediaService:

import { Injectable } from '@angular/core';
@Injectable()
export class MatchMediaService 
{
constructor()
{
}
rules =
{
print: "print",
screen: "screen",
phone: '(max-width: 767px)',
tablet: '(min-width: 768px) and (max-width: 1024px)',
desktop: '(min-width: 1025px)',
portrait: '(orientation: portrait)',
landscape: '(orientation: landscape)',
retina: '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)'
};
Check = function (mq)
{
if (!mq)
{
return;
}
return window.matchMedia(mq).matches;
};
/**********************************************
METHODS FOR CHECKING TYPE   
**********************************************/
IsPhone()
{
return window.matchMedia(this.rules.phone).matches;
};
IsTablet = function ()
{
return window.matchMedia(this.rules.tablet).matches;
};
IsDesktop = function ()
{
return window.matchMedia(this.rules.desktop).matches;
};
IsPortrait = function ()
{
return window.matchMedia(this.rules.portrait).matches;
};
IsLandscape = function ()
{
return window.matchMedia(this.rules.landscape).matches;
};
IsRetina = function ()
{
return window.matchMedia(this.rules.retina).matches;
};
/**********************************************
EVENT LISTENERS BY TYPE
**********************************************/    
OnPhone(callBack)
{
if (typeof callBack === 'function')
{
var mql: MediaQueryList = window.matchMedia(this.rules.phone);
mql.addListener((mql: MediaQueryList) =>
{
if (mql.matches)
{
callBack(mql);
}
});
}
};
OnTablet(callBack)
{
if (typeof callBack === 'function')
{
var mql: MediaQueryList = window.matchMedia(this.rules.tablet);
mql.addListener((mql: MediaQueryList) =>
{
if (mql.matches)
{
callBack(mql);
}
});
}
};
OnDesktop(callBack)
{
if (typeof callBack === 'function')
{
var mql: MediaQueryList = window.matchMedia(this.rules.desktop);
mql.addListener((mql: MediaQueryList) =>
{
if (mql.matches)
{
callBack(mql);
}
});
}
};  
OnPortrait(callBack)
{
if (typeof callBack === 'function')
{
var mql: MediaQueryList = window.matchMedia(this.rules.portrait);
mql.addListener((mql: MediaQueryList) =>
{
if (mql.matches)
{
callBack(mql);
}
});
}
};  
OnLandscape(callBack)
{
if (typeof callBack === 'function')
{
var mql: MediaQueryList = window.matchMedia(this.rules.landscape);
mql.addListener((mql: MediaQueryList) =>
{
if (mql.matches)
{
callBack(mql);
}
});
}
};
}

Puis à l'intérieur d'un "parent" composant (HomeComponent), j'utilise MatchMediaService pour déterminer quel composant enfant (HomeMobileComponent ou HomeDesktopComponent) à charge en fonction de ce que MatchMediaService renvoie aussi bien en tant qu'auditeur des événements déclenchés lorsque le navigateur est redimensionnée par le biais de différentes dimensions:

import { Component, OnInit, NgZone } from '@angular/core';
import { MatchMediaService } from '../shared/services/match-media.service';
import { HomeMobileComponent } from './home-mobile.component';
import { HomeDesktopComponent } from './home-desktop.component';
@Component({
moduleId: module.id,
selector: 'home.component',
templateUrl: 'home.component.html',
providers: [ MatchMediaService ],
directives: [ HomeMobileComponent, HomeDesktopComponent ]
})
export class HomeComponent implements OnInit 
{
IsMobile: Boolean = false;
IsDesktop: Boolean = false;
constructor(
private matchMediaService: MatchMediaService,
private zone: NgZone        
)
{
//GET INITIAL VALUE BASED ON DEVICE WIDTHS AT TIME THE APP RENDERS
this.IsMobile = (this.matchMediaService.IsPhone() || this.matchMediaService.IsTablet());
this.IsDesktop = (this.matchMediaService.IsDesktop());
var that = this;
/*---------------------------------------------------
TAP INTO LISTENERS FOR WHEN DEVICE WIDTH CHANGES
---------------------------------------------------*/
this.matchMediaService.OnPhone(
function (mediaQueryList: MediaQueryList)
{
that.ShowMobile();
}
);
this.matchMediaService.OnTablet(
function (mediaQueryList: MediaQueryList)
{
that.ShowMobile();
}
);
this.matchMediaService.OnDesktop(
function (mediaQueryList: MediaQueryList)
{
that.ShowDesktop();
}
);
}
ngOnInit()
{
}
ShowMobile()
{
this.zone.run(() =>
{ //Change the property within the zone, CD will run after
this.IsMobile = true;
this.IsDesktop = false;
});
}
ShowDesktop()
{
this.zone.run(() =>
{ //Change the property within the zone, CD will run after
this.IsMobile = false;
this.IsDesktop = true;
});
}   
}
<home-mobile *ngIf="(IsMobile)"></home-mobile>
<home-desktop *ngIf="(IsDesktop)"></home-desktop>

Cette approche fonctionne. Je peux charger le composant approprié en réponse à l'appareil. Il m'offre la possibilité de personnaliser un composant (contenu, style, fonctionnalité, etc) à l'appareil, permettant ainsi la meilleure expérience utilisateur. Cela aussi m'offre la possibilité de cibler des différents composants pour Mobile, Tablette et ordinateur de Bureau (bien que je ne me concentre sur mobile et ordinateur de bureau par exemple).

Est-il une meilleure façon de le faire? L'inconvénient, c'est que je suis obligeant chaque composant comporte le composant parent pour déterminer via MatchMediaService qui composant enfant à charge. Cela sera évolutive pour travailler dans une pleine soufflé niveau de production de l'app? Je suis très intéressé par vos commentaires sur une meilleure approche, ou si cette approche est acceptable et évolutive pour une pleine soufflé à la production de l'app. Merci pour vous commentaires.

InformationsquelleAutor Tom Schreck | 2016-07-18