3. APP FLOW
Do not forget about:
Form factors
App contracts
All type of the tiles
Toast notifications
Touch first
Animations
4. ASYNC PATTERNS
You should understand how:
to compose asynchronous code
to use promises
to chain and group promises
to code promise chains to avoid nesting
to wrap non-promise values in a promise
to handle errors in a promise
5. PROMISES
A promise is an object that represent a value that will be
available later.
Most API's are wraped to the promises.
All based on two methods .then and .done.
6. PROMISES
A promise is an object that represent a value that will be
available later.
HiloHiloimageQueryBuilder.js
i (hsstig.idbe {
f ti.etnsbnal)
/ Cet `ioPcue ojcsisedo rtrig`trgFl`ojcs
/ rae Hl.itr` bet nta f eunn Soaeie bet
qeyrms =qeyrms.hnti.cetVeMdl)
urPoie urPoiete(hs_raeiwoes;
}
9. BIND FUNCTION
Define funtion environment with .bind
HiloHiloTilesTileUpdater.js
vrqeeiepae =ti.uuTlUdtsbn(hs;
a uuTlUdts hsqeeiepae.idti)
qeeiepae:fnto (oiiain){
uuTlUdts ucin ntfctos
vrsl =ti;
a ef hs
ntfctosfrahfnto (oiiain {
oiiain.oEc(ucin ntfcto)
sl.iepae.paentfcto)
eftlUdtrudt(oiiain;
};
)
},
10. BIND FUNCTION
Bind can receive additional parameters.
HiloHiloTilescreateTileFriendlyImages.js
fnto cetTlFinlIae(ie){
ucin raeieredymgsfls
vrlclodr=apiainaacretlclodr
a oaFle plctoDt.urn.oaFle;
vrcpTubalTFle =cpFlsoodrbn(ul fls;
a oyhmnisoodr oyieTFle.idnl, ie)
vrweFleCetd=lclodrcetFleAyctubalodr
a hnodrrae oaFle.raeodrsn(hmniFle
Nm,cetoCliinpinrpaexsig;
ae rainolsoOto.elcEitn)
rtr weFleCetd
eun hnodrrae
.hncpTubalTFle)
te(oyhmnisoodr;
}
11. GROUPING A PROMISE
When you have non-sequential, asynchronous operations
that must all complete before you can continue a task, you can
use the WinJS.Promise.join
vrweFlIOe =treFl.pnsn(iecesoeraWie;
a hniespn agtieoeAycflAcsMd.edrt)
vrweTubiIRay=sucFl.eTubalsn(hmniMd.iget
a hnhmalsed oreiegthmniAyctubaloesnlI
e)
m;
vrweEeyhnIRay=WnSPoieji( oee:weFlIOe,ra
a hnvrtigsed iJ.rms.on{ pnd hniespn ed
y weTubiIRay};
: hnhmalsed )
12. HANDLING ERRORS
Use .done at the end of method chain.
It doesn't return another promise and throw unhandled
expetions.
14. MVP
The model represents the state and operations of business
objects that your app manipulates
The view (HTML and CSS) defines the structure, layout, and
appearance of what the user sees on the screen. The view
manages the controls on the page and forwards user events
to a presenter class
The presenter contains the logic to respond to events,
update the model and, in turn, manipulate the state of the
view
15. MVP - VIEW
HiloHilohubhub.html
<i i=hbiaetmlt"dt-i-oto=WnSBnigTmlt"
dv d"u-mg-epae aawncnrl"iJ.idn.epae>
<i dt-i-id"tl.akrudmg:ulbcgonUl at nm;
dv aawnbn=syebcgonIae r.akrudr; l: ae
casae casae cas"hmni"
lsNm: lsNm" ls=tubal>
<dv
/i>
<dv
/i>
16. MVP - PRESENTER TEST
HiloHilo.SpecficationsspecshubListViewPresenter.spec.js
dsrb(we sapd,fnto ( {
ecie"hn npe" ucin )
vre;
a l
bfrEc(ucin( {
eoeahfnto )
vrapiw={;
a pVe }
e =nwSesWnotoSu(;
l e pc.iCnrltb)
e.iCnrladvnLsee =fnto ( {}
lwnoto.dEetitnr ucin ) ;
vrlsvePeetr=nwHl.u.itiwrsne(l apiw
a itiwrsne e ioHbLsVePeetre, pVe)
;
lsvePeetrstiwtt(idw.IVeMngmn.plcto
itiwrsne.eVeSaeWnosU.iwaaeetApiai
niwtt.npe)
VeSaesapd;
};
)
i(teLsVe sol ueaLsLyu" fnto ( {
t"h itiw hud s itaot, ucin )
epc(lwnoto.aotisaco WnSU.itaot.qa(
xete.iCnrllyu ntnef iJ.ILsLyu)eult
re;
u)
};
)
};
)
17. PRESENTERS
Each presenter is responsible for a specific part of the page (a
control)
One page-specific presenter (the mediator) coordinates the
other presenters (control-specific) and receives forwarded
events
18. PRESENTERS
HiloHilodetaildetail.js
ray fnto (lmn,otos {
ed: ucin eeet pin)
vrqey=otosqey
a ur pin.ur;
vrqeyae=qeystig.otAder
a urDt ur.etnsmnhnYa;
vrpgTte=Hl.aeomte.eMnhrmqeyae +""+Hl
a aeil iodtFratrgtotFo(urDt) io
.aeomte.eYaFo(urDt)
dtFratrgterrmqeyae;
ti.idaeil(aeil)
hsbnPgTtepgTte;
vrhlApaE =dcmn.urSlco(#pbr)
a iopBrl ouetqeyeetr"apa";
vrhlApa =nwHl.otosHlApa.iopBrrsne(io
a iopBr e ioCnrl.iopBrHlApaPeetrhlA
pBrl WnSNvgto,qey;
paE, iJ.aiain ur)
vrflsrpl=dcmn.urSlco(#imti";
a imtiE ouetqeyeetr"flsrp)
vrfiveE =dcmn.urSlco(#lpiw)
a lpiwl ouetqeyeetr"five";
vrfivePeetr=nwHl.ealFivePeetrfiveE)
a lpiwrsne e ioDti.lpiwrsne(lpiwl;
vrflsrprsne =nwHl.ealFlsrprsne(imtiE
a imtiPeetr e ioDti.imtiPeetrflsrpl
);
vrdtiPeetr=nwHl.ealDtiPeetrflsrprsne
a ealrsne e ioDti.ealrsne(imtiPeet
r fivePeetr hlApa,WnSNvgto)
, lpiwrsne, iopBr iJ.aiain;
dtiPeetradvnLsee(pgSlce" fnto (rs {
ealrsne.dEetitnr"aeeetd, ucin ag)
vrieIdx=ag.ealieIdx
a tmne rsdti.tmne;
otosieIdx=ieIdx
pin.tmne tmne;
};
)
dtiPeetr
ealrsne
20. UPDATING TILES
Hilodefault.js
i (urnSaekn ==atvto.ciainidluc){
f crettt.id = ciainAtvtoKn.anh
i (urnSaepeiuEeuintt !=atvto.plctoEeui
f crettt.rvosxctoSae = ciainApiainxct
oSaetriae){
ntt.emntd
/ We teapi satd w wn t udt istl
/ hn h p s tre, e at o pae t ie
/ o tesatsre.Sneti AIi ntacsil
/ n h tr cen ic hs P s o cesbe
/ isd o Bed w ol ivk i we w aenti
/ nie f ln, e ny noe t hn e r o n
/ dsg md.
/ ein oe
i (WnosApiainoe.einoedsgMdEald {
f !idw.plctoMdlDsgMd.einoenbe)
vrtlUdtr=nwHl.ie.iepae(;
a iepae e ioTlsTlUdtr)
tlUdtrudt(;
iepae.pae)
}
}
21. UPDATING TILES
HiloHiloTilesTileUpdater.js
udt:fnto ( {
pae ucin )
/ Bn tefnto t acnet s ta `hs wl b rsle
/ id h ucin o otx, o ht ti` il e eovd
/ we i i ivkdi tepoie
/ hn t s noe n h rms.
vrqeeiepae =ti.uuTlUdtsbn(hs;
a uuTlUdts hsqeeiepae.idti)
/ Bidaqeyt gttenme o iae nee frtetls
/ ul ur o e h ubr f mgs edd o h ie.
vrqeyule =nwHl.mgQeyule(;
a urBidr e ioIaeurBidr)
qeyule.on(ubrfmgsoeree;
urBidrcutnmeOIaeTRtiv)
vrweIaeFrieeree =qeyule.ul(itrsirr)ee
a hnmgsoTlRtivd urBidrbidpcueLbay.xc
ue)
t(;
weIaeFrieeree
hnmgsoTlRtivd
.hnHl.ie.raeieredymgs
te(ioTlscetTlFinlIae)
.hnti.eLclmgPts
te(hsgtoaIaeah)
.hnHl.ie.raeiepae)
te(ioTlscetTlUdts
.hnqeeiepae)
te(uuTlUdts;
}
23. PAGE NAVIGATION
HiloDefault.html
<i i=cnetot dt-i-oto=Hl.aeotoNvgtr dt-i-
dv d"otnhs" aawncnrl"ioPgCnrlaiao" aawno
pin={oe 'Hl/u/u.tl}>
tos"hm: /iohbhbhm'"
<dv
/i>
HiloHilohubhubPresenter.js
ieCikd fnto (rs {
tmlce: ucin ag)
/ Gtte`ioPcue ie ta wsbudt teivkdiae
/ e h Hl.itr` tm ht a on o h noe mg,
/ adteie idxfo tels ve cnrl
/ n h tm ne rm h it iw oto.
vrpcue=ag.ealie.aa
a itr rsdti.tmdt;
/ Bidteqeyta cnfn ti pcuewti i' mnhgop
/ ul h ur ht a id hs itr ihn ts ot ru.
vrotos=ti.ulQeyoPcuepcue;
a pin hsbidurFritr(itr)
/ Nvgt t tedti ve,seiyn temnhqeyt
/ aiae o h eal iw pcfig h ot ur o
/ so,adteidxo teidvda ie ta wsivkd
/ hw n h ne f h niiul tm ht a noe.
ti.a.aiae"Hl/ealdti.tl,otos;
hsnvnvgt(/iodti/ealhm" pin)
},
24. CREATING PAGES
HiloHilohubhub.js
Hl.otospgsdfn(hb,{
iocnrl.ae.eie"u"
ray fnto (lmn,otos {
ed: ucin eeet pin)
/ Hnl teapbrbto cik frsoigadhdn teap
/ ade h p a utn lcs o hwn n iig h p
br
a.
vrapaE =dcmn.urSlco(#pbr)
a pBrl ouetqeyeetr"apa";
vrhlApa =nwHl.otosHlApa.iopBrrsne(
a iopBr e ioCnrl.iopBrHlApaPeetra
pBrl WnSNvgto)
paE, iJ.aiain;
/ Hnl slcigadivkn (lcig iae.
/ ade eetn n noig cikn) mgs
vrlsVeE =dcmn.urSlco(#itrsirr";
a itiwl ouetqeyeetr"pcueLbay)
ti.itiwrsne =nwHl.u.itiwrsne(itiwl
hslsVePeetr e ioHbLsVePeetrlsVeE,
WnosU.iwaaeetApiainiw;
idw.IVeMngmn.plctoVe)
/ Codnt teprso tehbpg.
/ oriae h at f h u ae
ti.uVePeetr=nwHl.u.uVePeetr
hshbiwrsne e ioHbHbiwrsne(
WnSNvgto,
iJ.aiain
hlApa,
iopBr
ti.itiwrsne,
hslsVePeetr
nwHl.mgQeyule(
e ioIaeurBidr)
);
ti.uVePeetr
hshbiwrsne
.tr(nwFlespcueLbay
satkonodr.itrsirr)
.hnfnto ( {
te(ucin )
WnSApiainadvnLsee(Hl:otnshne"
iJ.plcto.dEetitnr"ioCnetCagd,
Hl.aiao.eod;
ionvgtrrla)
25. SUPPORTING DIFFERENT LAYOUTS
HiloHiloPageControlNavigator.js
fnto PgCnrlaiao(lmn,otos {
ucin aeotoNvgtreeet pin)
/ ...
/
wno.neie=ti.rszdbn(hs;
idworsz hs_eie.idti)
/ ...
/
},
_eie:fnto (rs {
rszd ucin ag)
i (hspgCnrl& ti.aeoto.paeaot {
f ti.aeoto & hspgCnrludtLyu)
ti.aeoto.paeaotcl(hspgCnrl ti.aelmn
hspgCnrludtLyu.alti.aeoto, hspgEeet
,apiwvle ti.lsVesae;
pVe.au, hs_atiwtt)
}
ti.lsVesae=apiwvle
hs_atiwtt pVe.au;
},
26. SUPPORTING DIFFERENT LAYOUTS
HiloHilohubhub.js
udtLyu:fnto (lmn,veSae lsVeSae {
paeaot ucin eeet iwtt, atiwtt)
ti.itiwrsne.eVeSaeveSae lsVeSae;
hslsVePeetrstiwtt(iwtt, atiwtt)
},
HiloHilohublistViewPresenter.js
stiwtt:fnto (iwtt){
eVeSae ucin veSae
ti.vlyu =ti.eetaotveSae;
hsl.aot hsslcLyu(iwtt)
},
slcLyu:fnto (iwtt,lsVeSae {
eetaot ucin veSae atiwtt)
i (atiwtt ==veSae {rtr;}
f lsVeSae = iwtt) eun
i (iwtt ==apiwtt.npe){
f veSae = pVeSaesapd
rtr nwWnSU.itaot)
eun e iJ.ILsLyu(;
}
es {
le
vrlyu =nwWnSU.rdaot)
a aot e iJ.IGiLyu(;
lyu.ruIf =fnto ( {rtr lsVeLyuStig;}
aotgopno ucin ) eun itiwaotetns ;
lyu.aRw =3
aotmxos ;
rtr lyu;
eun aot
}
},
27. DATA BINDING
Templates for group items and group headers in the normal
view.
HiloHilomonthmonth.html
<i i=mnhtmepae dt-i-oto=WnSBnigTmlt"
dv d"otIeTmlt" aawncnrl"iJ.idn.epae>
<i dt-i-id"tl.akrudmg:ulbcgonUl casae
dv aawnbn=syebcgonIae r.akrudr; lsNm:
casae>/i>
lsNm"<dv
<dv
/i>
<i i=mnhruHaeTmlt"dt-i-oto=WnSBnigTmlt"
dv d"otGopedrepae aawncnrl"iJ.idn.epae>
< cas"otLn"he=#>sa dt-i-id"neHM:tte>/p
a ls=mnhik rf""<pn aawnbn=inrTL il"<s
a>(sa dt-i-id"neTx:cut>/pn)/>
n <pn aawnbn=inret on"<sa><a
<dv
/i>
<i i=mnhnpeTmlt"dt-i-oto=WnSBnigTmlt"
dv d"otSapdepae aawncnrl"iJ.idn.epae>
<pndt-i-id"neHM:tte>/pn (sa dt-i-id"ne
sa aawnbn=inrTL il"<sa> <pn aawnbn=in
ret cut>/pn)
Tx: on"<sa>
<i dt-i-id"tl.akrudmg:bcgonUl"cas"hmn
dv aawnbn=syebcgonIae akrudr; ls=tuba
i"<dv
l>/i>
<dv
/i>
28. DATA SOURCE TYPES
WinJS.Binding.List - synchronous data source, in-memory
data source (an array), all its data must be available for
display
StorageDataSource - built-in support for the Windows file
system
VirtualizedDataSource - custom implementation
29. UX
You should provide both pointer and touch experience to your
user.
The pointer is an old school, touch control requires some skills
from developer.
30. OBJECT ROTATION
HiloHilorotateTouchProvider.js
fnto Tuhrvdrosrco(nuEeet {
ucin ocPoieCntutriptlmn)
vrrcgie =nwWnosU.nu.etrRcgie(;
a eonzr e idw.IIptGsueeonzr)
rcgie.etrStig =WnosU.nu.etrStig.aiua
eonzrgsueetns idw.IIptGsueetnsmnplt
inoae
oRtt;
iptlmn.dEetitnr"SoneDw" fnto (v){
nuEeetadvnLsee(MPitron, ucin et
vrp =etcreton;
a p v.urnPit
i (ppitreiepitreieye==pitreieyetuh
f p.oneDvc.oneDvcTp = oneDvcTp.oc)
{
rcgie.rcsDwEetp)
eonzrpoesonvn(p;
}
} fle;
, as)
iptlmn.dEetitnr"SoneMv" fnto (v){
nuEeetadvnLsee(MPitroe, ucin et
vrps=etitreitPit;
a p v.nemdaeons
i (p[]& ps0.oneDvc.oneDvcTp ==pitre
f ps0 & p[]pitreiepitreieye = oneDv
ieyetuh {
cTp.oc)
rcgie.rcsMvEet(p)
eonzrpoesoevnsps;
}
} fle;
, as)
iptlmn.dEetitnr"SoneU" fnto (v){
nuEeetadvnLsee(MPitrp, ucin et
vrp =etcreton;
a p v.urnPit
i (ppitreiepitreieye==pitreieyetuh
f p.oneDvc.oneDvcTp = oneDvcTp.oc)
{
rcgie.rcsUEetp)
eonzrpoespvn(p;
}
31. PERFORMANCE TIPS
Limit the start time
Emphasize responsiveness
Use thumbnails for quick rendering
Retrieve thumbnails when accessing items
Release media and stream resources when they're no
longer needed
Optimize ListView performance
Keep DOM interactions to a minimum
Optimize property access
Use independent animations
Manage layout efficiently
Store state efficiently
Keep your app’s memory usage low when it's suspended
Minimize the amount of resources that your app uses
32. IN DEPTH
Bytecode caching is a technique in which the system creates
bytecode for each JavaScript file once, rather than re-creating
the bytecode each time it starts the app (30% improvment in
large apps).
Avoid synchronous API calls. Break proccessing operations
into series of smaller operations.
33. IN DEPTH
Use Windows Runtime thumbnail APIs to cache and show
thumbnails.
Use DOM objects only to store information that directly
affects how the DOM lays out or draws elements.
Certain types of animations are offloaded from the UI thread
to GPU-accelerated system thread.
34. IN DEPTH
Combine API calls to reduce the number of layout passes.
Store session data in the sessionState in-memory object.
When your app begins the suspension process, it should free
any large objects that can be easily rebuilt when it resumes.
35. WAYS TO TEST YOUR APP
Unit testing
Integration testing
UX testing
Security testing
Localization testing
Accessibility testing
Performance testing
Device testing
36. MOCHA
Hilo.SpecificationsspecsqueriesimageQueryBuilder.spec.js
dsrb(IaeQeyBidr,fnto ( {
ecie"mg ur ule" ucin )
vrqeyule,soaeodr
a urBidr trgFle;
bfrEc(ucin(oe {
eoeahfnto dn)
qeyule =nwHl.mgQeyule(;
urBidr e ioIaeurBidr)
vrweFle =WnosSoaeApiainaacretlclodr
a hnodr idw.trg.plctoDt.urn.oaFle.
gtodrsn(Idxd)
eFleAyc"nee";
weFle.hnfnto (odr {
hnodrte(ucin fle)
soaeodr=fle;
trgFle odr
dn(;
oe)
};
)
};
)
37. ASYNC TESTS
Hilo.SpecificationsspecsqueriesimageQueryBuilder.spec.js
dsrb(we eeuigaqeyta seiistenme o iae t la
ecie"hn xctn ur ht pcfe h ubr f mgs o o
d,fnto ( {
" ucin )
vrqeyeut
a urRsl;
bfrEc(ucin( {
eoeahfnto )
qeyeut=qeyule
urRsl urBidr
.on()
cut1
.ul(trgFle)
bidsoaeodr
.xct(;
eeue)
};
)
i(sol la teseiidnme o iae" fnto (oe {
t"hud od h pcfe ubr f mgs, ucin dn)
qeyeutte(ucin(mgs {
urRsl.hnfnto iae)
epc(mgslnt)eul()
xetiae.egh.qas1;
dn(;
oe)
}.oenl,dn)
)dn(ul oe;
};
)
};
)
38. HANDLING EXCEPTIONS
Mocha test runner should intercepts this exception and
reports it as a test failure.
But WinJS is intercepting all promises errors.
.done function is never called, test will go into a wait state and
Mocha will time out (2 seconds), omitting the fail message.