Successfully reported this slideshow.
Your SlideShare is downloading. ×

Intro to KnockoutJS

More Related Content

Intro to KnockoutJS

  1. 1. JOURNEY THROUGH MVC ARCHITECTURE USING KNOCKOUTJS KIANOSH POURIAN
  2. 2. WHO AM I? WEB DEVELOPER WITH 12+ YEARS EXPERIENCE IN FRONT END DEVELOPMENT WORKED ON PROJECTS FOR ISOBAR/MOLECULAR VMWARE MIT NOVARTIS BLOG AT: INNOVATORYLIFE.COM TWITTER: @KIANOSHP
  3. 3. WHAT IS MVC? THE IDEA BEHIND [MVC] IS TO MAKE A CLEAR DIVISION BETWEEN DOMAIN OBJECTS THAT MODEL OUR PERCEPTION OF THE REAL WORLD AND PRESENTATION OBJECTS THAT ARE THE UI ELEMENTS WE SEE ON THE SCREEN…DOMAIN OBJECTS SHOULD BE COMPLETELY SELF CONTAINED AND WORK WITHOUT REFERENCE TO THE PRESENTATION, THEY SHOULD ALSO BE ABLE TO SUPPORT MULTIPLE PRESENTATION, POSSIBLY SIMULTANEOUSLY. MARTIN FOWLER
  4. 4. MV* OR MVWTF (MVC, MVP, MVVM, ETC...) BACKBONEJS EMBER JAVASCRIPTMVC KNOCKOUTJS BATMANJS WHATEVER THE LATEST FRAMEWORK THAT HAS BEEN WRITTEN IN THE LAST HOUR...
  5. 5. MV* REFERENCE TODO MVC SITE UNDERSTANDING MVVM JAVASCRIPT MVC JUNGLE KNOCKOUTJS ANY ARTICLE BY ADDY OSMANI
  6. 6. BENEFITS OF MV* FRAMEWORK SEPARATION OF CONCERNS EASIER OVERALL MAINTENANCE SIDE BY SIDE DEVELOPMENT ORGANIZATION
  7. 7. A COMPLEX SYSTEM THAT WORKS IS INVARIABLY FOUND TO HAVE EVOLVED FROM A SIMPLE SYSTEM THAT WORKS. JOHN GAULE
  8. 8. WHAT IS MVVM? MVVM WAS ORIGINALLY DEFINED BY MICROSOFT FOR USE WITH WINDOWS PRESENTATION FOUNDATION (WPF) AND SILVERLIGHT, HAVING BEEN OFFICIALLY ANNOUNCED IN 2005 BY JOHN GROSSMAN IN A BLOG POST ABOUT AVALON (THE CODENAME FOR WPF). IT ALSO FOUND SOME POPULARITY IN THE ADOBE FLEX COMMUNITY AS AN ALTERNATIVE TO SIMPLY USING MVC.
  9. 9. MODEL THE MODEL IN MVVM REPRESENTS DOMAIN-SPECIFIC DATA OR INFORMATION THAT OUR APPLICATION WILL BE WORKING WITH. A TYPICAL EXAMPLE OF DOMAIN- SPECIFIC DATA MIGHT BE A USER ACCOUNT (E.G NAME, AVATAR, E-MAIL) OR A MUSIC TRACK (E.G TITLE, YEAR, ALBUM). MODELS WILL HOLD THE INFORMATION BUT TYPICALLY DO NOT HANDLE THE BEHAVIOR.
  10. 10. VIEW THE VIEW IS THE PART OF APPLICATION THAT THE USER IS ABLE TO VIEW AND INTERACT WITH THE DATA. THE VIEW WILL NOT MANIPULATE OR CHANGE THE DATA THAT IS THE JOB OF THE CONTROLLER OR IN THIS CASE THE VIEWMODEL.
  11. 11. VIEWMODEL THE VIEWMODEL, AS THE NAME SUGGESTS, IS THE GO BETWEEN THE VIEW AND THE MODEL. THE VIEWMODEL CAN BE CONSIDERED A SPECIALIZED CONTROLLER THAT ACTS AS A DATA CONVERTER. IT CHANGES MODEL INFORMATION INTO VIEW INFORMATION, PASSING COMMANDS FROM THE VIEW TO THE MODEL. FOR EXAMPLE, THE MODEL MAY CONTAIN A BOOLEAN VALUE LIKE ISAVAILABLE, IT IS UP TO THE VIEWMODEL TO INTERPRET THAT AND DISPLAY THE CORRECT INFORMATION TO THE USER.
  12. 12. WHY USE KNOCKOUTJS? DECLARATIVE BINDINGS: EASILY ASSOCIATE DOM ELEMENTS WITH MODEL DATA USING A CONCISE, READABLE SYNTAX AUTOMATIC UI REFRESH: WHEN YOUR DATA MODEL'S STATE CHANGES, YOUR UI UPDATES AUTOMATICALLY DEPENDENCY TRACKING: IMPLICITLY SET UP CHAINS OF RELATIONSHIPS BETWEEN MODEL DATA, TO TRANSFORM AND COMBINE IT TEMPLATING: QUICKLY GENERATE SOPHISTICATED, NESTED UIS AS A FUNCTION OF YOUR MODEL DATA
  13. 13. EXAMPLE FLICKER APP
  14. 14. MODEL VAR FAVORITES, PHOTO; PHOTO = FUNCTION(ID, OWNER, TITLE, FARMID, SERVERID, SECRET, ISPUBLIC, ISFRIEND, ISFAMILY) { THIS.ID = ID; THIS.OWNER = OWNER; THIS.TITLE = TITLE; THIS.FARMID = FARMID; THIS.SERVERID = SERVERID; THIS.SECRET = SECRET; THIS.ISPUBLIC = ISPUBLIC; THIS.ISFRIEND = ISFRIEND; THIS.ISFAMILY = ISFAMILY; }; FAVORITES = FUNCTION(PHOTO) { RETURN THIS.PHOTO = PHOTO; };
  15. 15. VIEW <DIV ID="RESULTS" DATA-BIND="TEMPLATE: 'PHOTOS-TEMPLATE'"></DIV> ... <SCRIPT TYPE="TEXT/HTML" ID="PHOTOS-TEMPLATE"> <UL CLASS="CLEARFIX"> {{EACH PHOTOS}} ! <LI CLASS="FLT-LEFT"><IMG SRC="${PHOTOSRC}" ALT="$ {PHOTOOBJ.TITLE}-${PHOTOOBJ.OWNER}" TITLE="${PHOTOOBJ.TITLE}" /></ LI> {{/EACH}} </UL> </SCRIPT>
  16. 16. VIEWMODEL VAR PHOTOVIEWMODEL = { PHOTOS: KO.OBSERVABLEARRAY([]), FAVORITES: KO.OBSERVABLEARRAY([]), ... };
  17. 17. VIEWMODEL (CONTINUED) VAR PHOTOVIEWMODEL = { ... GETPHOTOS: FUNCTION(FORMELEMENT) { VAR SEARCHTAG, THAT; SEARCHTAG = $(FORMELEMENT).FIND('#SEARCH').VAL(); THAT = THIS; $.GETJSON(FLICKRURL + SEARCHTAG).DONE(FUNCTION(PHOTODATA) { RETURN _.EACH(PHOTODATA.PHOTOS.PHOTO, FUNCTION(PHOTO) { VAR IMAGE; IMAGE = { PHOTOOBJ: NEW PHOTO(PHOTO.ID, PHOTO.OWNER, PHOTO.TITLE, PHOTO.FARM, PHOTO.SERVER, PHOTO.SECRET, PHOTO.ISPUBLIC, PHOTO.ISFRIEND, PHOTO.ISFAMILY), PHOTOSRC: THAT.CREATESRCTHUMBNAIL(PHOTO.FARM, PHOTO.SERVER, PHOTO.ID, PHOTO.SECRET) }; RETURN THAT.PHOTOS.PUSH(IMAGE); }); }); }, ... };! ! ! ! ! ! ! !
  18. 18. VIEWMODEL (CONTINUED) VAR PHOTOVIEWMODEL = { ... CREATESRC: FUNCTION(FARMID, SERVERID, ID, SECRET, SIZE) { RETURN 'HTTP://FARM' + FARMID + '.STATICFLICKR.COM/' + SERVERID + '/' + ID + '_' + SECRET + (SIZE === "THUMBNAIL" ? "_S.JPG" : "_N.JPG"); }, ... };! !
  19. 19. TRUE SEPARATION OF CONCERNS COMMON COMPLAINT OF KNOCKOUTJS IS THE WHAT SEEMS LIKE THE MIXING OF JAVASCRIPT, DATA-BIND ATTRIBUTES, AND MARKUP. HOWEVER KNOCKOUTJS ALLOWS YOU TO CREATE CUSTOM BINDINGS. BINDING PROVIDER IMPLEMENTS TWO FUNCTIONS: NODEHASBINDINGS: THIS TAKES IN A DOM NODE WHICH DOESN’T NECESSARILY HAVE TO BE AN ELEMENT GETBINDINGS: RETURNS AN OBJECT REPRESENTING THE BINDINGS AS APPLIED TO THE CURRENT DATA CONTEXT
  20. 20. DATA-CLASS BINDING ONE OPTION TO COMBAT THE OVERLY TIED APPLICATION LOGIC TO THE VIEW IS TO CREATE A CUSTOM BINDING SIMILAR TO CSS CLASSES. RYAN NIEMEYER HAS SUGGESTED THIS PROCEDURE. IN ORDER TO ACCOMPLISH THIS, ONE HAS TO CUSTOMIZE THE NODEHASBINDINGS AND GETBINDINGS FUNCTIONS.
  21. 21. DATA-CLASS BINDING VAR BINDINGS = { RETRIEVEPHOTOS: { SUBMIT: VIEWMODEL.GETPHOTOS }, RENDERPHOTOTEMPLATE : { TEMPLATE: 'PHOTOS-TEMPLATE' } };! ! !
  22. 22. DATA-CLASS BINDING KO.CUSTOMBINDINGPROVIDER = FUNCTION(BINDINGOBJECT) { THIS.BINDINGOBJECT = BINDINGOBJECT; THIS.NODEHASBINDINGS = FUNCTION(NODE) { RETURN NODE.GETATTRIBUTE ? NODE.GETATTRIBUTE("DATA-CLASS") : FALSE; }; }; THIS.GETBINDINGS = FUNCTION(NODE, BINDINGCONTEXT) { VAR RESULT = {}; VAR CLASSES = NODE.GETATTRIBUTE("DATA-CLASS"); IF (CLASSES) { CLASSES = CLASSES.SPLIT(' '); FOR (VAR I = 0, J = CLASSES.LENGTH; I < J; I++) { VAR BINDINGACCESSOR = THIS.BINDINGOBJECT[CLASSES[I]]; IF (BINDINGACCESSOR) { VAR BINDING = TYPEOF BINDINGACCESSOR == "FUNCTION" ? BINDINGACCESSOR.CALL(BINDINGCONTEXT.$DATA) : BINDINGACCESSOR; KO.UTILS.EXTEND(RESULT, BINDING); } } } RETURN RESULT; }; };! ! ! ! ! ! ! !
  23. 23. DATA-CLASS BINDING // SET KO'S CURRENT BINDINGPROVIDER EQUAL TO OUR NEW BINDING PROVIDER KO.BINDINGPROVIDER.INSTANCE = NEW KO.CUSTOMBINDINGPROVIDER(BINDINGS); // BIND A NEW INSTANCE OF OUR VIEWMODEL TO THE PAGE KO.APPLYBINDINGS(VIEWMODEL); })();
  24. 24. KNOCKBACKJS KNOCKBACKJS COMBINES THE ADVANTAGES OF BACKBONEJS AND KNOCKOUTJS CREATING A RATHER UNIQUE SOLUTION TO THE SHORTCOMINGS OF EITHER FRAMEWORK. BACKBONE'S ORM BACKBONES'S BUILT-IN SERIALIZATION/DESERIALIZATION KNOCKOUT'S MVVM FRAMEWORK KNOCKOUT'S DATA-BIND SORCERY BACKBONE'S ROUTING AND HISTORY SUPPORT KNOCKBACK'S PROPER SEPARATION OF CONCERNS
  25. 25. THANK YOU TWITTER: @KIANOSHP BLOG: INNOVATORYLIFE.COM PRESENTATION INFO: HTTP://KIANO.SH/RIB8KH

Editor's Notes

  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

×