sencha touch 2 quick start

12
Based on: ‘Sencha Touch OpenSource HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Contents of document: The Class System The Component System The Event System Selectors Data Package And more… Sencha Touch 2 Quick Start The Sencha Touch class system allows creation of new JavaScript classes, providing inheritance, dependency loading, mixins, configuration options, and more. Ext.define('Motercycle',{ config: { buildYear: null, topSpeed: null, price: null }, constructor: function (config) { this.initConfig(config); }, isExpensive: function () { return this.getPrice() > 2000; } }); Ext.define('SuperBike',{ extend: 'Motercycle', config: { model: null, brand: null }, isSuzuki: function () { return this.getBrand() === 'Suzuki'; }, isExpensive: function () { return this.getPrice() > 10000; } }); We defined a Motorcycle class with a Superbike subclass. The Motorcycle class has some basic properties defined in the config object. Besides class properties we defined some basic class methods as well. The Superbike class extends the Motorcycle class and thereby inherits its properties and methods. In addition we are able to define a unique implementation of each method. We can instantiate a class by using Ext.create instead of the new keyword. Using the former leverages Sencha Touch’s dynamic dependency loader and allows for using aliases, as well as easily applying the config object. var hondaMotercycle = Ext.create('Motercycle',{ buildYear: 2002, topSpeed: 180, price: 2000 }); The Class System hondaMotercycle.isExpensive(); //returns false hondaMotercycle.getPrice(); //returns 2000 var suzukiGSXR = Ext.create('SuperBike',{ buildYear: 2015, topSpeed: 300, price: 12000, model: 'gsxr1000', brand: 'Suzuki' }); suzukiGSXR.isExpensive(); //returns true suzukiGSXR.getModel(); //returns "gsxr1000" You may notice the use of some functions that we have not explicitly defined, for example getModel(). The Sencha Touch class system does us a favor and generates 4 types of convenience functions: Getter – return current value; getName() Setter – set new value; setName() Applier called by setter, execute logic when property changes; applyName() Updater – called by setter, execute logic when the value for a property changes; updateName() TIP Please note that the applier and updater functions require implementation. The applier function requires a return of the value that will be set to the property. The updater gets fired after the applier and does not handle a return, rather, it just informs of a value change Let’s assume we want to round the price of the Motercycle to the nearest 1000. To do so we would implement the applyPrice function in the Motercycle class: applyPrice : function (newPrice, oldPrice) { return Math.round(newPrice / 1000) * 1000; } Usage: hondaMotercycle.setPrice(1995); hondaMotercycle.getPrice(); //returns 2000

Upload: khangminh22

Post on 29-Apr-2023

1 views

Category:

Documents


0 download

TRANSCRIPT

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Contents  of  document:  Ø The  Class  System  Ø The  Component  System  Ø The  Event  System  Ø Selectors  Ø Data  Package  Ø And  more…  

Sencha  Touch  2  Quick  Start  

   

 The   Sencha   Touch   class   system   allows   creation   of   new  JavaScript   classes,  providing   inheritance,  dependency   loading,  mixins,  configuration  options,  and  more.    

Ext.define('Motercycle',  {     config:  {       buildYear:  null,       topSpeed:  null,       price:  null     },     constructor:  function  (config)  {       this.initConfig(config);     },     isExpensive:  function  ()  {       return  this.getPrice()  >  2000;     }  });  Ext.define('SuperBike',  {     extend:  'Motercycle',     config:  {       model:  null,       brand:  null     },     isSuzuki:  function  ()  {       return  this.getBrand()  ===  'Suzuki';     },     isExpensive:  function  ()  {       return  this.getPrice()  >  10000;     }  });    We  defined  a  Motorcycle  class  with  a  Superbike  subclass.  The  Motorcycle   class   has   some   basic   properties   defined   in   the  config  object.    Besides  class  properties  we  defined  some  basic  class   methods   as   well.   The   Superbike   class   extends   the  Motorcycle   class   and   thereby   inherits   its   properties   and  methods.   In   addition   we   are   able   to   define   a   unique  implementation  of  each  method.    We   can   instantiate   a   class   by   using   Ext.create   instead   of   the  new   keyword.   Using   the   former   leverages   Sencha   Touch’s  dynamic   dependency   loader   and   allows   for   using   aliases,   as  well  as  easily  applying  the  config  object.    

var  hondaMotercycle  =  Ext.create('Motercycle',  {     buildYear:  2002,     topSpeed:  180,     price:  2000  });  

 

The  Class  System    

hondaMotercycle.isExpensive();     //returns  false  hondaMotercycle.getPrice();     //returns  2000    var  suzukiGSXR  =  Ext.create('SuperBike',  {     buildYear:  2015,     topSpeed:  300,     price:  12000,     model:  'gsxr1000',     brand:  'Suzuki'  });  suzukiGSXR.isExpensive();     //returns  true  suzukiGSXR.getModel();     //returns  "gsxr1000"  

 You  may   notice   the   use   of   some   functions   that  we   have   not  explicitly  defined,  for  example  getModel().  The  Sencha  Touch  class   system   does   us   a   favor   and   generates   4   types   of  convenience  functions:  

• Getter  –  return  current  value;  getName()  • Setter  –  set  new  value;  setName()  • Applier   –   called   by   setter,   execute   logic   when  

property  changes;  applyName()  • Updater   –   called   by   setter,   execute   logic   when   the  

value  for  a  property  changes;  updateName()    

TIP  

Please   note   that   the   applier   and   updater  functions   require   implementation.   The  applier  function  requires  a  return  of  the  value  that  will  be   set   to   the  property.  The  updater  gets   fired   after   the   applier   and   does   not  handle   a   return,   rather,   it   just   informs   of   a  value  change  

 Let’s  assume  we  want  to  round  the  price  of  the  Motercycle  to  the   nearest   1000.   To   do   so   we   would   implement   the  applyPrice  function  in  the  Motercycle  class:    

applyPrice  :  function  (newPrice,  oldPrice)  {     return  Math.round(newPrice  /  1000)  *  1000;  }  

 Usage:    

hondaMotercycle.setPrice(1995);  hondaMotercycle.getPrice();     //returns  2000  

   

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

 A   crucial   requirement   for   many   mobile   applications   is   to  consume   data   from   external   sources   as   well   as   maintain  internal   application   specific   data.   For   these   situations   Sencha  Touch  provides   the  Data  Package,  a   set  of   classes   responsible  for  loading,  storing,  manipulating  and  saving  data.      Three  types  of  classes  generally  leverage  the  data  package:    

• Model  –  an  entity  that  represents  a  single  record,  defining  its  fields,  validation,  associations  and  conversion  parameters.      

• Store  –  collection  of  model  instances  with  support  for  sorting,  filtering,  and  grouping      

• Proxy  –  medium  that  interacts  with  the  remote  or  local  data  source  and  performs  the  necessary  reading  and  writing  operations.      

 Models  Models  are  data  objects  that  are  managed  in  your  application.  Models  are  defined  by  a  set  of  data  fields.  Each  field  is  defined  by  its  name,  type,  and  optional  defaultValue.    Supported  field  types  are:  

• string      • int      • float      • boolean      • date      

 A   convert   function   can   also   be   implemented   on   the   field   to  perform  processing  on  the  field’s  data.    Here  is  a  sample  model:    

Ext.define('MyApp.model.Car',  {     extend:  'Ext.data.Model',     config  :  {       fields  :  [         {  name:  'make',     type:  'string'  },         {  name:  'model',   type:  'string'  },         {  name:  'topSpeed',   type:  'int'        },         {  name:  'price',   type:  'float'    },         {  name:  'options',  type:  'auto'      }       ]     }  });    Data  Proxies  There  are   four  proxies  provided  by  Sencha  Touch   that  can  be  used  in  a  Store  or  Model.  

• LocalStorage  –  saves  data  to  localStorage      • Memory  –  saves  data  in  memory,  extremely  volatile      • Ajax  –  communicates  with  a  RESTful  resource  on  the  

same    domain      • JsonP  –  communicates  with  a  service  on  an  external  

domain    using  JSON-­‐P    Each  proxy  type  implements  four  basic  operations  create,  read,  update,  and  destroy.    When   interacting   with   Server   Proxies,   there   is   a   need   for  serializing  the  data  sent  and  retrieved  from  the  server.  For  this    

Data  Package  Sencha   Touch   provides   the   JsonReader,   JsonWriter,  XmlReader   and   XmlWriter   classes.   These   reader   and  writer  types  are  specified  on  the  proxy  definition.    Example  Store  with  Proxy    

Ext.define('MyApp.store.Cars',  {     extend:  'Ext.data.Store',     requires  :  [       'Ext.data.reader.Json',       'Ext.data.writer.Json'       ],     config:  {       model:  'MyApp.model.Car',       proxy:  {         type:  'ajax',         url:  '/cars',         reader:  {           type  :  'json',           rootProperty:  'cars'         }       }     }  });    

TIP  

Proxies  can  be  attached  to  both  Models  and  Stores.  The  result  is  the  same,  the  Store  will  be  looking  for  a  Proxy  config  on  itself  and  if  none   is   present   it   will   look   for   it   on   the  Model.     However,   if   the   Proxy   is   defined  inside   the  Model,   multiple   Stores   using   the  same  Model  don’t  have   to  define   the  config.    Furthermore,   defining   a   Proxy   inside   a  Model   allows   you   to   save   and   load   an  instance   of   that   Model   without   needing   a  Store    

 To   access   a   store   from  anywhere   in   the   application   you   can  use   the  Ext.   getStore()   function   and  pass   in   either   a  defined  storeId  or  the  store’s  classname,  excluding  namespace.    Example  of  loading  data  into  a  store:    

Ext.getStore("Cars").load();    

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

 

The  Component  System    

 

Common  Components    The   Sencha   Touch   Component   system   is   the   foundation   of   all  the  visual  elements   in   the   framework.  The  Component   system  makes   full  use  of   the  Class   system’s  dependency   injection  and  hierarchical   support.   Every   Sencha   Touch   view   class   is   a  subclass   of   Ext.Component,   and   thus   follows   its   lifecycle.  Components   are   generally   defined   by   an   xtype.   An  xtype   is   a  shortcut   for   the   full   component   Class   name   allowing   for   lazy  instantiation.   Using   xtypes   to   instantiate   components   allows  the   creation   of   the   object   to   be   deferred   to  when   it’s   actually  needed,  thus  saving  resources.      There   may   be   times   when   you   want   to   display   multiple  components,   either   all   at   once   or   individually.   The  Ext.Container   class   exists   for   these   situations.   Containers  provide   functionality   for   adding   child   Components,   removing  Components   and   specifying   a   Layout   that   determines   how  these  components  are  displayed.    

 

Component   Purpose   Useful  Properties  &  Functions  

Component  Ext.Component  xtype:  component    

Basic  Visual  Class     xtype    cls    html    tpl    data  show()  /  hide()  /destroy()    

Container  Ext.Container  xtype:  container    

Manages  Component  rendering  and  arrangement    

layout    items    scrollable    add(component)  /  remove(component)    

Panel  Ext.Panel  xtype:  panel    

Container  designed  to  float  as  overlays    

showBy(component)    

Toolbar  Ext.Toolbar  xtype:  panel    

Docked  containers  that  generally  hold  Buttons  and  a  Title    

title    left  /  right    ui    

Button  Ext.Button  xtype:  button    

Basic  tappable  component    

text    ui    iconCls    iconAlign    

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Tab  Panel  Ext.tab.Panel  xtype:  tabpanel    

Container  that  allows  user  to  easily  switch  between  components  using  a  Toolbar    

tabBarPosition    

MessageBox  Ext.Msg  Ext.MessageBox    

Modal  Container  for  displaying  alerts  and  notifications.  Ext.Msg  is  a  singleton  that  allows  for  creation  of  predefined  MessageBox  instances.    

Ext.Msg.alert(title,  msg,  callback)    Ext.Msg.confirm(title,  msg,  callback)    Ext.Msg.prompt(title,  msg,  callback)    

Carousel  Ext.Carousel    xtype:  carousel    

Container  that  allows  user  to  switch  active  components  by  swiping    

ui    direction    indicator    next()  /  previous()    

List  Ext.dataview.List  xtype:  list    

Container  of  dynamically  rendered  components  from  a  Data  Store    

store    itemTpl    itemCls    onItemDisclosure    grouped    indexBar    

Form  Panel  Ext.form.Panel  xtype:  formpanel    

Panel  that  contains  a  set  of  form  fields  to  be  displayed    

getValues()  /    setValues(data)    submit(options,  params,  headers)    

Form  Fields  Ext.field.Field  xtype:  field    

Base  class  for  all  data  input  form  fields    

name    label  /  labelCls  /  labelAlign    inputCls    required    

 Layouts    Layouts   describe   the   sizing   and   positioning  on  Components  inside   your   app.   For   example,   an   email   client  might  have  a   list  of  messages  pinned  to  the   left,   taking  up  one  third  of  the  available  width,  and  a  message  viewing  panel  in  the  rest  of  the  screen.    We   can   achieve   this   using   an   hbox   layout   and   its   ability  to  ‘flex’  items   within   it.   Flexing   means   that   we   divide   the  available   area  based  on   the  flexof   each   child   component,   so   to  achieve  our  example  above  we  can  set  up   flexes   like  shown   in  the  following  image:    

   In  the  code  for  this  layout  we  need  to  specify  the  ‘hbox’  layout  on  any  Container,  then  supply  a  flex  parameter  for  each  of  the  child  components  (Panels  in  this  case)  as  follows:  Docking  

Ext.create('Ext.Container',  {     fullscreen:  true,     layout:  'hbox',     items:  [       {         xtype:  'panel',         html:  'message  list',         flex:  1       },       {         xtype:  'panel',         html:  'message  preview',         flex:  2       }     ]  });  

 Vbox  layout    

 Card  layout  Sometimes   you   want   to   show   several   information   screens  information   on   a   small   device   screen.   TabPanels   and  Carousels   both   enable   you   to   see   one   screen   of   many   at   a  time,  and  underneath  they  both  use  a  Card  Layout.    Card   Layout   takes   the   size   of   the   Container   it   is   applied   to  and  sizes  the  currently  active  item  so  as  to  completely  fill  the  Container.  It  then  hides  the  rest  of  the  items,  allowing  you  to  change  which  one  is  currently  visible,  but  only  showing  one  at  once:  

 Fit  layout  The  Fit  Layout  is  probably  the  simplest  layout  available.  All  it  does  is  make  a  child  component  fit  the  full  size  of  its  parent  Container.  

 

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Every  layout  is  capable  of  docking  items  inside  it.  Docking  enables  you  to  place  additional  Components  at  the  top,  right,  bottom,  or  left  edges  of  the  parent  Container,  resizing  the  other  items  as  necessary.  

   

XTemplate    Template  based  components  have  been  the  norm  in  many  web  applications   thanks   to   frameworks   like  Mustache,  Handlebars,  Closure,   and   more.   Sencha   Touch   provides   first   class  functionality  for  templating  through  the  Ext.XTemplate  class.      The   Ext.XTemplate   class   supports   not   only   simple   data  identifiers  but  also:    

• Array  traversal      • Conditional  processing      • Basic  math  functionality      • Execute  arbitrary  code      • Execute  custom  template  functions      

 When   defining   an   XTemplate,   the   tpl   tag   is   reserved   for  template  commands.        Array  Traversal  Looping  through  an  array  is  done  with  the  tpl  for  keyword  with  the  value  being  either  "."  or  a  property  path.    

TIP  While  iterating  the  array,  there  are  two  special  variables  {#}  and  {.}.  {#}  represents  the  current  index  of  the  array  +  1.  {.}  represents  the  value  of  the  element  at  the  current  index  

 Example  assuming  the  data  is  an  array  of  Car  objects:    

<tpl  for=".">     <div>{make}  {model}</div>  </tpl>  

 Example   assuming   the   data   is   an   object   with   a   cars   property  that  holds  arrays  grouped  by  make:    

<tpl  for="cars.toyota">     <div>{#}  {.}</div>  </tpl>  

 

Conditional  Processing  XTemplate  supports  4  basic  comparison  operations:  if,  else-­‐if,  else,  and  switch.    Examples:    

<tpl  for="cars">     <div>{make}  {model}  is       <tpl  if="topSpeed  &gt;  150">         <span>ridiculously  fast</span>       <tpl  elseif="topSpeed  &gt;  80">         <span>somewhat  fast</span>       <tpl  else>         <span>ridiculously  slow</span>       </tpl>     </div>  </tpl>  <div>  {make}  is  <tpl  switch="{make}">     <tpl  case="BMW"  case="Mercedes-­‐Benz"  case="Audi">       <span>luxurious</span>     <tpl  default>       <span>economical</span>  </tpl>    Math  Support  The  following  math  operators  are  supported:  +    -­‐    *    /    Example:    

<tpl  for="cars">     <div>Top  Speed  in  km/h  is  {topSpeed  *  1.6}</div>  </tpl>  

 Executing  Arbitrary  Code  It  is  possible  to  execute  JavaScript  code  while  in  the  scope  of  the  template  by  using  []  inside  an  expression.      While  executing  code  inside  a  template  expression  there  are  several  special  values  available:    

• out  –  output  array  of  the  template      • values  –  values  in  the  current  scope      • parent  –  values  of  parent  data  object      • xindex   –   if   in   looping   template,   then   the   1-­‐based  

index    • xcount   –   if   in   looping   template,   then   the   total  

length  of  array  Example:    

<tpl  for="cars">     <div>{[values.make.toUpperCase()  +  "  -­‐  "  +  values.model.toLowerCase()]}</div>  </tpl>    Custom  Template  Function  When   defining   our   Ext.XTemplate   instance,   we   can  implement  functions  that  will  be  executed  by  the  template.    Example:  (See  next  page)    

   

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

var  tpl  =  new  Ext.XTemplate  (     '<tpl  for="cars">',       '<div>  {make}  is',       '<tpl  if="this.isFast(make)">',         '<span>fast!</span>',       '<tpl  else>',         '<span>slow</span>',       '</tpl>',     '</tpl>',     {       isFast  :  function  (make)  {         return  (make  ===  "Ferrari");       }     }  );    

Theming    An  important  aspect  of  any  application  is  styling  and  theming.  Sencha  Touch  applications  are  styled  using  SASS  and  compiled  with  Compass.    

TIP  Compass  requires  Ruby  to  be  installed  on  your  computer  and  can  be  installed  using  rubygems.  More  information  can  be  found  here:  http://compass-­‐style.org/  More  information  on  SASS  can  be  found  at:  http://sass-­‐lang.com/  

 Common  Global  SASS  Variables    Variable     Description    $base-­‐color     Primary  color  that  most  elements  

reference    $base-­‐gradient     Primary  gradient  color  most  elements  

reference    $font-­‐family     Font  family  used  throughout  the  theme    $page-­‐bg-­‐color     Background  color  of  fullscreen  

components      Common  Global  SASS  Mixins    Mixin     Description    pictos-­‐iconmask($name)    

Include  a  base64-­‐encoded  icon  to  be  used  with  Tab  Buttons.  Name  must  match  icon‘s  file  name  in  resources/themes/images/  default/pictos  without  extension    @include  pictos-­‐iconmask(‘wifi2‘);    

bevel-­‐text($type)     Add  text  shadow  or  highlight.  $type  is  either  shadow  or  highlight.    

stretch()     Stretch  an  element  to  parent‘s  bounds    

ellipsis()     Apply  element  text-­‐overflow  to  use  ellipsis    

 

 A  crucial  part  of  the  Component  and  Application  life  cycle  in  general  are  the  events  that  are  fired  at  different  stages.  These  events   can   be   triggered   from   some   interaction   with   a  component  or  be  fired  after  some  arbitrary  business  logic  is  executed.  Most  importantly,  for  each  event  we  can  configure  simple  listeners  to  handle  these  events.      We   react   to   events   by   attaching   event   listeners   on   a   given  component   through   the   listeners   property   or   the   on()  function  where  we  pass   in   an  object  where   the  event  name  maps  to  a  callback.  When  we  define  the  listeners,  we  can  also  attach   the  context   that   the  callback  gets  executed   in  via   the  scope  property.      

myButton.on({     tap  :  function  ()  {       console.log("button  tap");     },     scope  :  this    });    Common  Events  Fired  by  Components    

• painted  –  fires  when  element  becomes  rendered  on  the  screen      

• show  /  hide  –  fires  when  view  component,  generally  a  modal,  is    shown  or  hidden  using  show()  and  hide()      

• updatedata  –  fires  when  data  of  component  is  updated    

Common  Events  Fired  by  Containers      • activate  /  deactivate  –  fires  when  an  item  in  the  

container  is  activated  or  deactivated      • activeitemchange  –  (card  layout  only)  fires  when  

the  actively  visible  item  is  changed  by  setActiveItem()      

• add  /  remove  –  fires  when  components  are  added  or  removed  from  container      

 Sencha  Touch  allows  us  to  also  manage  events  that  are  fired  by   the  DOM  elements   that   these   components   render.  These  DOM   elements   are   of   type   Ext.dom.Element.   The   elements  fire  events  for  native  browser  gesture  interactions.      Here   is   an   example   of   attaching   event   listeners   for   both  component   and   element   events.   You   can   also   see   some  simple   event   handler   implementation   as   well   as   firing   of  custom  events.        

Ext.define("MyApp.view.tooltip.Tooltip",  {     extend:  "Ext.Panel",     xtype:  "tooltip",     config:  {       /*  ...  */     },     initialize  :  function  ()  {         var  me  =  this;       me.element.on({         tap  :  me.onTap,         touchstart  :  me.onTouchStart,         /*  Continued  on  the  next  page  */  

 

The  Event  System  

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

      touchend  :  me.onTouchEnd,         scope  :  me       });             me.on({         show  :  me.onShow,         hide  :  me.onHide,         scope  :  me       });           me.callParent();     },     onTap  :  function  (evtObj)  {       this.fireEvent('close');     },     onTouchStart  :  function  (evtObj)  {       var  closeButton  =  evtObj.getTarget(".close-­‐button");       if  (closeButton)  {         Ext.fly(closeButton).addCls('pressed');       }     },     onTouchEnd  :  function  (evtObj)  {       var  closeButton  =  evtObj.getTarget(".close-­‐button");       closeButton  &&  Ext.fly(closeButton).removeCls('pressed');     },     onShow  :  function  ()  {       /*  ...  */     },     onHide  :  function  ()  {       this.destroy();     }  });    Common  Events  Fired  by  Elements    

• tap  -­‐  fires  for  every  tap      • doubletap  -­‐  fires  for  a  double  tap      • taphold  /  longpress  -­‐  fires  for  when  you  hold  a  tap  

for  >  1    second      • touchstart  /  touchend  -­‐  fires  for  when  the  touch  

starts  and    finishes      • drag  -­‐  continuously  fires  for  dragging      • dragstart  /  dragend  -­‐  fires  when  dragging  begins  and  

finishes      • pinch  /  rotate  -­‐  continuously  fires  for  pinch  and  

rotate  gestures      swipe  -­‐  fires  when  there  is  a  swipe;  the  event  property  holds  the  swipe  direction    

Selectors    One   of   the   most   useful   functionalities   of   Sencha   Touch   and  ExtJS   as   well   is   the   support   for   finding   the   instance   of   a  component   or   DOM   element.   Similar   to   jQuery’s   $   selector,  Sencha  Touch  provides  the  child(),  up(),  down()  and  query()  functions   to   each   Container   class.   These   functions   take   in   a  ComponentQuery   Selector   and   return   either   the   first  component   (child(),   up(),   down())   or   an   array   of   all  matching  components  (query()).  You  can  also  query  for  components  on  a  global   scope   by   using   the   Ext.   ComponentQuery   singleton,  which  has  a  query()  method.      

 Selector  Type   Purpose   Example  

xtype     Select  component  based  on  its  xtype    

Ext.ComponentQuery.query(‘.  formpanel‘);    myContainer.down(‘.button‘);    

itemId  /  id     Select  component  based  on  its  itemId  or  id  property    

Ext.ComponentQuery.  query(‘#myFirstPanel‘);    myContainer.down(‘#submit‘);    

Attribute     Select  a  component  based  on  its  xtype  and  some  property  value  that  is  set  on  it    

myFormPanel.down("field[name=  userName]);    

Nested  Selector    

Select  a  child  of  a  matched  selector    

Ext.ComponentQuery.query(‘panel  >  toolbar‘);    

Multiple  Selector    

Select  children  that  match  multiple  selectors    

Ext.ComponentQuery.  query(‘formpanel,  carousel‘);    

 

TIP  We  can  also  query  on  DOM  Elements.  The  Ext.dom.Element  class  provides  query()  and  down()  functions.  Here  however  we  use  CSS  selectors.  More  information  on  CSS  Selectors  can  be  found  here:  http://www.w3.org/TR/selectors/  

   

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Cheat  Sheet    List  of  Sencha  defined  xtypes  xtype                                                             Class  -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐                               -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  actionsheet                                     Ext.ActionSheet  audio                                                                      Ext.Audio  button                                                       Ext.Button  component                                     Ext.Component  container                                             Ext.Container  image                                                           Ext.Img  label                                                               Ext.Label  loadmask                                             Ext.LoadMask  map                                                                 Ext.Map  mask                                                             Ext.Mask  media                                                         Ext.Media  panel                                                           Ext.Panel  segmentedbutton             Ext.SegmentedButton  sheet                                                             Ext.Sheet  spacer                                                         Ext.Spacer  title                                                                   Ext.Title  titlebar                                                     Ext.TitleBar  toolbar                                                     Ext.Toolbar  video                                                             Ext.Video  carousel                                                 Ext.carousel.Carousel  carouselindicator               Ext.carousel.Indicator  navigationview                       Ext.navigation.View  datepicker                                       Ext.picker.Date  picker                                                         Ext.picker.Picker  pickerslot                                           Ext.picker.Slot  slider                                                             Ext.slider.Slider  thumb                                                         Ext.slider.Thumb  tabbar                                                         Ext.tab.Bar  tabpanel                                                 Ext.tab.Panel  tab                                                                     Ext.tab.Tab  viewport                                             Ext.viewport.Default    DataView  Components  -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  dataview                                             Ext.dataview.DataView  list                                                                     Ext.dataview.List  listitemheader                         Ext.dataview.ListItemHeader  nestedlist                                           Ext.dataview.NestedList  dataitem                                               Ext.dataview.component.DataItem    Form  Components  -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  checkboxfield                             Ext.field.Checkbox  datepickerfield                       Ext.field.DatePicker  emailfield                                           Ext.field.Email  field                                                                 Ext.field.Field  hiddenfield                                                    Ext.field.Hidden  input                                                                            Ext.field.Input  numberfield                                 Ext.field.Number  passwordfield                           Ext.field.Password  radiofield                                           Ext.field.Radio  searchfield                                       Ext.field.Search  selectfield                                         Ext.field.Select  sliderfield                                         Ext.field.Slider  spinnerfield                                   Ext.field.Spinner  textfield                                                 Ext.field.Text  textareafield                               Ext.field.TextArea  textareainput                             Ext.field.TextAreaInput  togglefield                                         Ext.field.Toggle  urlfield                                                     Ext.field.Url  fieldset                                                       Ext.form.FieldSet  formpanel                                         Ext.form.Panel      

List  of  pictos  icon  set  available  in  Sencha  

 

TIP  

By  default   Sencha  Touch  2  does  not   include  the   full   icon   list   to   keep   the   Stylesheet  lightweight.  If  you  wanted  to  include  an  icon  that  is  not  available  in  the  default  list  below,  you  would  have  to  add  the  following  to  your  .SCSS  file:  

@include  icon('network');  

 Default  included  pictos  iconCls  list  (see  icons  above)    action  add  arrow_down  arrow_left  arrow_right  arrow_up  bookmarks  compose  delete  download  favorites  home    info    locate  

maps  more  organize  refresh  reply  search  settings  star  team  time  trash  user    

 

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

 MVC    Previously  we   introduced  Views  and  Models.  Now,   it’s   time   to  connect   them   together   to   form   a   full-­‐fledged   application   by  adding  in  a  Controller  concept.    Controller  Sencha   Touch   implements   the   Controller   through   the  Ext.app.Controller   class.   The   Controller   is   responsible   for  responding  to  events  that  your  components  may  fire.  There  are  two   core   configuration   properties   of   the   Controller:   ref   and  control.  

• refs   –   execute   ComponentQuery   to   locate   first  component   instance   to   match   selector   and   generate  getter  function  

• control   –   listen   to   events   from   ComponentQuery  selectors  or  refs  and  attach  listeners  

 Controller  Example:    

Ext.define('MyApp.controller.Main',  {     extend:  'Ext.app.Controller',     config:  {       refs:  {         loginPanel:  'loginpanel',         loginButton:  'loginpanel  button[text="login"]'       },       control:  {         loginpanel:  {           validate:  'onLoginPanelValidate'         },         loginButton:  {           tap:  'onLoginButtonTap'         }       }     },     onLoginPanelValidate  :  function  ()  {       this.getLoginPanel().validate();     },     onLoginButtonTap  :  function  ()  {       this.getLoginPanel().submit();     }  });    Application  Now   that  we   have  Models,   Views,   and   Controllers   defined  we  need   a  way   to   connect   them   together   so   that   they   can   coexist  and   work   with   each   other.   For   this   we   have   the  Ext.app.Application   class   that   connects   Models,   Controllers,  Profiles,   Stores   and   Views   together   by   instantiating   them  through  the  dependency  loader.    All   Sencha   Touch   applications   begin   with   a   call   to   the  Ext.application  function  that  creates  an  Application  instance.    Example  Application  instance:    

Ext.application({     name:  'MyApp',    

models  :  [       'Car',       'User'     ],     /*  Continued  on  the  right  */  

 

  stores  :  [       'Cars',       'Users'     ],     views  :  [         'LoginPanel',       'CarDetailView'     ],     controllers  :  [       'Main'     ],     launch  :  function  ()  {       Ext.fly('appLoadingIndicator').destroy();     }  });  

 

Packaging  /  Deploying    Since  Sencha  Touch  is  a  full-­‐fledged  application  framework  it  is   only   fitting   that   there   exists   a   tool   supporting   the  application’s  entire  life  cycle.    Sencha   Cmd   is   a   command   line   utility   that   provides  automated   tasks   from   generating   a   new   application   to  generating   components   of   an   existing   application   to  preparing  an  application  for  production  deployment.    Sencha  Cmd  contains  the  following  major  features:  

• Code  generation      • Optimized   Sencha   specific   JavaScript   minifier  

and  obfuscator      • Native   Packager   to   wrap   mobile   web  

application  as  a  native    hybrid  application  using  Phonegap/Cordova  

• Workspace   management   allows   sharing   code  between    applications  

 

TIP  

You  may  notice  that  when  we  specify  the  models,  stores,  views,  and  controllers  we  do  not  include  the  necessary  namespaces.  You  can  also  specify  models,  stores  and  views  in  Controllers.  In  the  Ext.  app.Application  and  Ext.app.Controller  class,  Sencha  Touch’s  loader  looks  up  the  dependency  based  on  the  context  provided  in  the  configuration.  

 Example  Usage    Generate  New  Application  

Sencha  generate  app  MyApp  /path/to/MyApp  

 Generate  Models,  Controller  and  Views  

cd  /path/to/MyApp  sencha  generate  model  Car  make:string,model:string,price:float  sencha  generate  controller  Main  sencha  generate  view  CarDetailView  

 Generate  New  Application  

sencha  app  build  [-­‐d  ‘testing’|’production’|’package’|’native’]    

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Sencha  Best  Practices    Avoid  hardcoded  ids  and  Ext.getCmp  Sencha   Touch   generates   a   unique   random   id   and   registers   it  with   the  ComponentManager.   It   is   possible   to   force   a   static   id  for   your   component   and   retrieve   it   using   the   Ext.getCmp(id)  function.   However,   as   your   project   and   number   of   developers  grow,  the  chance  that  the  static  ID  that  you  thought  would  stay  unique   diminishes.   Thus,   it   is   recommended   to   use   either  itemId,  which   assigns   a  pseudo-­‐id   and   is   scoped   locally   to   the  Container,  or  to  use  ComponentQuery.    Useful  References:  

• http://extjs.eu/writing-­‐a-­‐big-­‐application-­‐in-­‐ext/    Avoid  Controller  refs  with  multiple  instances  Generally,   it   is   a   good   practice   to   make   your   components  generic   enough   to   be   reusable   or   extensible   throughout   your  application.  Often,  when  defining  a  Controller  ref,  it  is  forgotten  that   it   only   returns   the   first   instance   that   matches   the  ComponentQuery   selector.   Thus,   it   is   recommended   to   use   a  ComponentQuery   inside   your   event   listener   to   determine   the  proper  instance  of  the  desired  Component  you  need.    Avoid  over-­‐nesting  Containers  Sencha   Touch   Containers   do   an   excellent   job   in   maintaining  their   child   components   and   making   sure   they   are   displayed  properly.   To   accomplish   this   task,   there   is   a   lot   of   calculation  and  manipulation  of  the  DOM  involved  in  the   layout  managers  of   these  containers.   It   is  easy   to  begin  carelessly  nesting   these  containers  inside  of  each  other.  When  the  containers  are  nested  it  becomes  much  more  processor  intensive  to  calculate  how  to  display   the   components   and   their   underlying   DOM   elements  properly.    Reduce  reliance  on  built-­‐in  Components  Many   of   Sencha   Touch’s   components   are   designed   to   be  widgets  that  are  meant  to  be  items  of  a  Container  and  arranged  by   the   layout   manager.   While   this   is   acceptable   in   certain  simple   situations,   it   often   results   in   unnecessary   utilization   of  the   DOM.   Sencha   Touch   allows   us   to   create   custom   views   by  leveraging   XTemplate   and   controlling   the   markup   of   our  component  to  be  as  minimal  as  necessary.    Do  not  edit  the  Framework  code  Yes,  delve  into  it,  read  it,  test  it,  learn  from  it  –  but  don’t  edit  it!  If  you  start  making  changes  to  the  core  library,  whether  it  is  the  JS   or   CSS,   you   are   planting   a   ticking   time-­‐bomb   into   your  application.  When  you  come  to  upgrade  to  a  newer  version  all  those  changes  will  be  lost  and  you  will  have  to  traipse  through  trying  to  figure  out  where  things  are  broken!    If  you  want  to  alter  the  behavior/look  of  the  framework  then  go  for  it  but  do  it  by  overriding  the  class  (be  it  a  JS  class  or  a  CSS  class)  or  method  in  a  separate  script  file.  By  doing  this  you  can  remove   it   if   necessary   and   keep   track   of   it   when   it   comes   to  reviewing  those  changes  when  new  versions  are  released.  

Be  careful  of  spaghetti  Code/Scope  Don’t  define  all  your  components  in  one  big  file  or  all  inline  –  it   will   be   a   nightmare   to   debug   and   your   scope   will   be   all  over   the   place.  Make   things   easy   and   split   each   component  definition   into   its  own   file  and  extend   the  base  class   to  add  your   configuration   and   extra   methods   and   behavior.   This  way  you  can  simply  instantiate  these  components  where  you  need  them  keeping  things  nice  and  tidy  and  loosely  coupled.    Make  sure  you  use  Namespaces  Again,   it’s   all   about   organization.   Utilize   the   built-­‐in  namespace   capabilities   of   Sencha   Touch   to   organize   your  components   and   classes   so   it’s   easy   to   navigate   later.  Typically  you  would  want  to  do  this  by  functional  module,  for  example,  MyApp.Users   for   all   the   User  management   code.   I  like   to   mirror   this   namespace   structure   with   the   folder  structure  so  everything  is  dead  easy  to  find.    Use  Get/Set  methods  or  Static  references  Don’t   be   tempted   to   delve   into   a   component’s   items   or  toolbar  collections  to  get  a  reference  to  a  particular  button  or  panel   using   ‘comp.get(0)’   or   comp.getTopToolbar().get(1)’  syntax.   If   you   ever   add   items   to   these   collections   the  references   will   be   broken   and   you  will   have   to   track   them  down.   In   a   big   application   this   becomes   a   mammoth   task,  which  will  introduce  bugs.    Save  yourself  some  hassle  and,  in  the  extended  class,  create  a  get  method  for  the  necessary  components,  which  delves  into  the   collection,   so   when   you   do   add   more   items   you   know  there   is   only   one   method   to   be   updated.   Or,   if   you   aren’t  concerned  about   lazy   instantiation,  define  your  buttons  and  items  as  class  variables  and  reference  them  that  way  so  you  won’t  need  to  make  any  updates  when  new  items  are  added.    Name  your  xtypes  carefully  Name   your   xtypes   the   same   as   your   class,   including  namespaces,   so   you   can   track   down   the   actual   class  definition   very   easily.   Additionally,   it   is   recommended   to  write  your  xtypes  with  lowercase  letters  only.    Always  have  the  Docs  open  The   API   documentation   is   your   best   friend   –   it   should   be  your   first  port  of   call  when   running   into  problems  or  when  trying  something  new.  Intellisense  for  Ext  JS  isn’t  quite  up  to  the  standards  of  Visual  Studio  for  .NET  so  we  can’t  get  away  with  being  so  lazy  –  the  docs  are  the  answer  to  this.  They  are  well  laid  out  and  easy  to  navigate,  so  make  use  of  them!    Use  Plugins  and  User  Extensions  If   you   want   a   component   to   do   something   that   is   fairly  generic  and  a  common  functional  requirement  it  is  likely  that  someone  has  already  coded   it  and  released   it  as  a  Plugin  or  an  Extension.  Take  some  time  before  coding   it   from  scratch  (unless   you   have   the   time   –   it’s   a   great   way   to   learn!)   to  search   the   forums   and   the   web   for   a   pre-­‐made   solution  (Sencha  marketplace).  

References    • http://www.swarmonline.com/technology/articles-­‐and-­‐videos/20-­‐things-­‐to-­‐avoiddo-­‐when-­‐getting-­‐started-­‐with-­‐ext-­‐js-­‐and-­‐sencha-­‐touch/  • Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy  

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Always  have  a  Utility  file  It   is   recommended   to   always   maintain   a   Utility   file   in   your  application.      Here  we  can  manage  all  general   information   like  API   url   details,   function   to   handle   errors,   showing   alert  messages   etc.   You   can  make   a   class  with   a   statics   object   and  put  it  in  a  separate  “util”  folder  under  the  “app”  folder.    Utility.js    

Ext.define('MyApp.utils.Utility',  {     statics:  {       BASE_URL:  'http://example.com/API/'     }  });    Some  where  in  the  application    

//  Use  properties  and  methods  as  follows  var  url  =  MyApp.utils.Utility.BASE_URL  console.log(url)  //  returns  "http://example.com/API/"  

 Maintain  all  templates  inside  index.html  In  almost  all  the  examples  and  tutorials  you  will  see  people  add  tpl  or  itemTpl  with  lots  of  html  tags  as  strings.  It  becomes  very  irritating   to  debug,   change  and   format  because  most  of  us  use  IDEs  and  html  inside  Javascript  files.  One  way  to  solve  this  is  by  adding  the  templates  inside  the  index.html  file  like  this:    Templates  inside  index.html    

<!-­‐-­‐  Sales  Rep  TPL  Info  -­‐-­‐>  <script  type="text/template"  id="tpl_sales_rep_info">     <div  class="black-­‐box  sales-­‐rep-­‐details"  id="sales_rep_info_block">       <div  class="name">{name}</div>       <div><a  href="tel:{phone}">{phone}</a></div>       <div><a  href="mailto:{email}">{email}</a></div>     </div>  </script>    <!-­‐-­‐  Sales  Rep  TPL  Input  -­‐-­‐>  <script  type="text/template"  id="tpl_sales_rep_input">     <div  class="contact-­‐us">       <div  class="black-­‐box">         <div  class="value">           Enter  your  zip  code         </div>       </div>       <div  class="black-­‐box">         <div  class="label">Zip  Code</div>         <div  class="value">           <input  type="text"  name="sales_rep_zip"  id="sales_rep_zip"/>         </div>       </div>     </div>  </script>  

 

We  keep  all   the  html   fragments   inside  SCRIPT   tag,   so   these  html  elements  are  not  added  in  the  DOM  and  you  can  access  the   data   simply   by   accessing   innerHTML   of   the   Script   tags.  This  works  perfectly  fine  while  creating  builds  and  template  codes  in  Views  become  easy  to  maintain.    Sample  tpl    

var  touchTeam  =  Ext.create('Ext.DataView',  {     store:  'MyStore',     itemTpl:  document.getElementById('tpl_sales_rep_input').innerHTML  });    Recommended  debugging  chain  How  you  should  go  about  fixing  a  problem…    

1. Check  your  Code  (it’s  easy  to  misspell  config  options,  miss  commas  etc)    

2. Refer  to  the  Documentation  (you  might  be  missing  a  related  config  option)    

3. Step  into  the  Framework’s  Source  Code  (break  into  the  code  around  the  error  and  try  to  see  what’s  going  wrong,  you’ll  likely  discover  a  config  option  you’ve  missed,  or  realize  something  you  expected  to  be  there  isn’t  instantiated  yet)    

4. Search  the  Forum  (it’s  almost  a  guarantee  that  someone  will  have  had  the  same  problem  and  posted  a  question  about  it)    

5. Search  the  wider  WWW  (if  the  forum  can’t  help  the  wider  web  might  be  able  to)    

6. Post  on  the  Forum  (if  you  still  can’t  find  the  resolution,  create  a  new  thread  with  as  much  detail  about  the  problem  as  you  can  –  make  it  easy  for  people  to  help  you)  

 Build  and  load  Widgets  on  Demand  When   possible,   build   and   load   widgets   on   demand.   Don’t  create   and   load   all   the   widgets   upon   application   launch.  Follow  a  load  strategy  based  on  the  user’s  role  in  the  app  so  you   only   load   the   UI   elements   that   the   user   will   need.   For  example,  you  don’t  have   to   load   the  administration  UI  of  an  app   if   the   user   is   not   in   the   administrators   role.   Your   UI  performs  better  and  is  more  stable  when  you  don’t   load  the  DOM  with  elements  that  you  will  not  use.    Limit  the  amount  of  data  rendered  in  the  UI  Do   not   transfer   large   amounts   of   data   from   the   server   or  local   storage   to   the   UI,   in   particular   to   data-­‐bound  components   such   as   grids,   lists   and   combo   boxes.   Large  numbers  of  records  take  memory.  They  also  slow  down  data-­‐bound  widgets’  rendering  and  performance.  Use  server-­‐side  and  client-­‐side  paging  and  filtering  to  limit  what  you  render  in  the  app.  

References  • http://www.innofied.com/sencha-­‐touch-­‐coding-­‐guidelines-­‐you-­‐should-­‐follow-­‐part-­‐1/  • http://miamicoder.com/2015/sencha-­‐touch-­‐best-­‐practices-­‐for-­‐user-­‐interface-­‐development/  

   

Based  on:  ‘Sencha  Touch  -­‐  Open-­‐Source  HTML5  Mobile  Web  Development  Made  Easy’  by  Stan  Bershadskiy    

Design   for  Offline  Mode  and  Optimize  Access   to  Local  Data  Your  application  should   function  without  having   to   talk   to   the  server  all  the  time,  unless  there  are  very  specific  requirements  to  connect   frequently.  This  approach  has   implications  for  your  UI  design.  Your  data-­‐bound  widgets  should  read  data  cached  in  local   storage,   local   files   or   local   databases   that   you   refresh   as  needed  when  there  is  a  connection  with  the  server.  Get  only  the  data  needed,  cache  it  locally,  and  perform  fast  reads  and  writes.    Avoid  Tight  Coupling  of  UI  Elements  Don’t  make   a  widget   be   aware   or   depend   on   the   existence   of  another  widget.  For  those  widgets  that  react  to  events  triggered  by   other  widgets,   use   controllers   to   handle   the   events.   If   two  widgets   are   governed   by   different   controllers,   don’t   let  controller  A  be  aware  of  widget  B  that’s  under  controller  B.  Use  controller  to  controller  links  via  events.    With  this  approach  it’s  easier  to  modify  parts  of  the  UI  without  impacting  other  UI  elements  or  application  modules.    Don’t  Block  the  UI  Don’t   make   your   users   wait.   Prevent   the   UI   from   becoming  unresponsive   when   the   app   is   executing   long-­‐running  operations,   such   as   server   calls   and   local   data   loading   and  filtering.  Trigger   long   running  operations   and  use   callbacks   to  be  notified  upon  completion.  Use  timeouts  to  limit  wait  periods.  Be   mindful   of   timers   and   functions   that   execute   on   intervals  and  might  block  the  UI.  Avoid  complex  drawing  and  animations,  they  affect  UI  performance.    Well  formed  code  Use   tools   like   JSLint,   JSHint,   Esprima,   etc.   to   help   you   detect  errors   and   potential   problems   in   your   JavaScript   code.   These  tools   also   help   you   structure   your   JavaScript   code   to   increase  readability  and  maintainability.  

 

References  • https://speakerdeck.com/arthurakay/best-­‐practices-­‐for-­‐enterprise-­‐javascript-­‐applications