SlideShare una empresa de Scribd logo
1 de 25
JOURNEY THROUGH MVC
  ARCHITECTURE USING
     KNOCKOUTJS
      KIANOSH POURIAN
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
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
MV* OR MVWTF (MVC, MVP,
       MVVM, ETC...)

BACKBONEJS

EMBER

JAVASCRIPTMVC

KNOCKOUTJS

BATMANJS

WHATEVER THE LATEST FRAMEWORK THAT HAS BEEN
WRITTEN IN THE LAST HOUR...
MV* REFERENCE


TODO MVC SITE

UNDERSTANDING MVVM

JAVASCRIPT MVC JUNGLE

KNOCKOUTJS

ANY ARTICLE BY ADDY OSMANI
BENEFITS OF MV* FRAMEWORK



SEPARATION OF CONCERNS

EASIER OVERALL MAINTENANCE

SIDE BY SIDE DEVELOPMENT

ORGANIZATION
A COMPLEX SYSTEM THAT WORKS IS INVARIABLY FOUND
TO HAVE EVOLVED FROM A SIMPLE SYSTEM THAT WORKS.

                                  JOHN GAULE
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.
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.
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.
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.
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
EXAMPLE FLICKER APP
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;
 };
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>
VIEWMODEL

VAR PHOTOVIEWMODEL = {
     PHOTOS: KO.OBSERVABLEARRAY([]),
     FAVORITES: KO.OBSERVABLEARRAY([]),
     ...
  };
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);
         });
       });
    },
...
};! !     !     !   !   !    !   !
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");
    },
...
};! !
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
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.
DATA-CLASS BINDING
VAR BINDINGS = {
        RETRIEVEPHOTOS: { SUBMIT: VIEWMODEL.GETPHOTOS },
        RENDERPHOTOTEMPLATE : { TEMPLATE: 'PHOTOS-TEMPLATE' }
};! !   !
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;
    };
};! !      !   !   !   !    !   !
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);
})();
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
THANK YOU



TWITTER: @KIANOSHP

BLOG: INNOVATORYLIFE.COM

PRESENTATION INFO: HTTP://KIANO.SH/RIB8KH

Más contenido relacionado

La actualidad más candente

MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...jaxconf
 
Backbone.js and friends
Backbone.js and friendsBackbone.js and friends
Backbone.js and friendsGood Robot
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databindingBoulos Dib
 
Sencha Touch - Introduction
Sencha Touch - IntroductionSencha Touch - Introduction
Sencha Touch - IntroductionABC-GROEP.BE
 
Анатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zАнатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zLEDC 2016
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todaygerbille
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityRyan Weaver
 
Five class-based views everyone has written by now
Five class-based views everyone has written by nowFive class-based views everyone has written by now
Five class-based views everyone has written by nowJames Aylett
 
Jquery tutorial-beginners
Jquery tutorial-beginnersJquery tutorial-beginners
Jquery tutorial-beginnersIsfand yar Khan
 
Intro to Angular.JS Directives
Intro to Angular.JS DirectivesIntro to Angular.JS Directives
Intro to Angular.JS DirectivesChristian Lilley
 
How to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.xHow to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.xAndolasoft Inc
 
Using RequireJS with CakePHP
Using RequireJS with CakePHPUsing RequireJS with CakePHP
Using RequireJS with CakePHPStephen Young
 
The rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screeningsThe rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screeningschicagonewsyesterday
 

La actualidad más candente (20)

MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
 
Backbone.js and friends
Backbone.js and friendsBackbone.js and friends
Backbone.js and friends
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databinding
 
Sencha Touch - Introduction
Sencha Touch - IntroductionSencha Touch - Introduction
Sencha Touch - Introduction
 
Анатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to zАнатолий Поляков - Drupal.ajax framework from a to z
Анатолий Поляков - Drupal.ajax framework from a to z
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Five class-based views everyone has written by now
Five class-based views everyone has written by nowFive class-based views everyone has written by now
Five class-based views everyone has written by now
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Events Lecture Notes
Events Lecture NotesEvents Lecture Notes
Events Lecture Notes
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Jquery tutorial-beginners
Jquery tutorial-beginnersJquery tutorial-beginners
Jquery tutorial-beginners
 
Intro to Angular.JS Directives
Intro to Angular.JS DirectivesIntro to Angular.JS Directives
Intro to Angular.JS Directives
 
How to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.xHow to migrate Cakephp 1.x to 2.x
How to migrate Cakephp 1.x to 2.x
 
Knockoutjs
KnockoutjsKnockoutjs
Knockoutjs
 
Using RequireJS with CakePHP
Using RequireJS with CakePHPUsing RequireJS with CakePHP
Using RequireJS with CakePHP
 
Web components
Web componentsWeb components
Web components
 
The rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screeningsThe rise and fall of a techno DJ, plus more new reviews and notable screenings
The rise and fall of a techno DJ, plus more new reviews and notable screenings
 

Destacado

Would you like some Grids with that?
Would you like some Grids with that?Would you like some Grids with that?
Would you like some Grids with that?Kianosh Pourian
 
Passport Nodejs Lightening Talk
Passport Nodejs Lightening TalkPassport Nodejs Lightening Talk
Passport Nodejs Lightening TalkKianosh Pourian
 
Express Presentation
Express PresentationExpress Presentation
Express Presentationaaronheckmann
 
Node, express & sails
Node, express & sailsNode, express & sails
Node, express & sailsBrian Shannon
 
We got to france!
We got to france! We got to france!
We got to france! bekyteckno
 
Modeljeans
ModeljeansModeljeans
Modeljeansyolimary
 
Why are preprocessors divisive
Why are preprocessors divisiveWhy are preprocessors divisive
Why are preprocessors divisiveKianosh Pourian
 
Palestra pré processadores CSS
Palestra pré processadores CSSPalestra pré processadores CSS
Palestra pré processadores CSSJust Digital
 

Destacado (11)

Would you like some Grids with that?
Would you like some Grids with that?Would you like some Grids with that?
Would you like some Grids with that?
 
Passport Nodejs Lightening Talk
Passport Nodejs Lightening TalkPassport Nodejs Lightening Talk
Passport Nodejs Lightening Talk
 
Express Presentation
Express PresentationExpress Presentation
Express Presentation
 
Node, express & sails
Node, express & sailsNode, express & sails
Node, express & sails
 
We got to france!
We got to france! We got to france!
We got to france!
 
It seminar 1.0
It seminar 1.0It seminar 1.0
It seminar 1.0
 
Modeljeans
ModeljeansModeljeans
Modeljeans
 
Why are preprocessors divisive
Why are preprocessors divisiveWhy are preprocessors divisive
Why are preprocessors divisive
 
Social job search
Social job searchSocial job search
Social job search
 
Node.js with Express
Node.js with ExpressNode.js with Express
Node.js with Express
 
Palestra pré processadores CSS
Palestra pré processadores CSSPalestra pré processadores CSS
Palestra pré processadores CSS
 

Similar a Intro to KnockoutJS

Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Nativetlv-ios-dev
 
Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Yuriy Shapovalov
 
Javascript frameworks: Backbone.js
Javascript frameworks: Backbone.jsJavascript frameworks: Backbone.js
Javascript frameworks: Backbone.jsSoós Gábor
 
MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!Roberto Messora
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data BindingEric Maxwell
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components EverywhereIlia Idakiev
 
Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Ovadiah Myrgorod
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"GeeksLab Odessa
 
Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Revath S Kumar
 
Single Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsSingle Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsPrateek Dayal
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSGunnar Hillert
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Natasha Murashev
 

Similar a Intro to KnockoutJS (20)

Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4Single Page Applications on JavaScript and ASP.NET MVC4
Single Page Applications on JavaScript and ASP.NET MVC4
 
MVVM Lights
MVVM LightsMVVM Lights
MVVM Lights
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
Javascript frameworks: Backbone.js
Javascript frameworks: Backbone.jsJavascript frameworks: Backbone.js
Javascript frameworks: Backbone.js
 
MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!MV* presentation frameworks in Javascript: en garde, pret, allez!
MV* presentation frameworks in Javascript: en garde, pret, allez!
 
Jsf intro
Jsf introJsf intro
Jsf intro
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
 
Backbone js
Backbone jsBackbone js
Backbone js
 
Web Components Everywhere
Web Components EverywhereWeb Components Everywhere
Web Components Everywhere
 
Backbone js-slides
Backbone js-slidesBackbone js-slides
Backbone js-slides
 
Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02
 
Single Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsSingle Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and Rails
 
Create and Maintain COMPLEX HIERARCHIES easily
Create and Maintain COMPLEX HIERARCHIES easilyCreate and Maintain COMPLEX HIERARCHIES easily
Create and Maintain COMPLEX HIERARCHIES easily
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
Fundaments of Knockout js
Fundaments of Knockout jsFundaments of Knockout js
Fundaments of Knockout js
 

Último

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 

Último (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 

Intro to KnockoutJS

  • 1. JOURNEY THROUGH MVC ARCHITECTURE USING KNOCKOUTJS KIANOSH POURIAN
  • 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. 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. 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. MV* REFERENCE TODO MVC SITE UNDERSTANDING MVVM JAVASCRIPT MVC JUNGLE KNOCKOUTJS ANY ARTICLE BY ADDY OSMANI
  • 6. BENEFITS OF MV* FRAMEWORK SEPARATION OF CONCERNS EASIER OVERALL MAINTENANCE SIDE BY SIDE DEVELOPMENT ORGANIZATION
  • 7. A COMPLEX SYSTEM THAT WORKS IS INVARIABLY FOUND TO HAVE EVOLVED FROM A SIMPLE SYSTEM THAT WORKS. JOHN GAULE
  • 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. 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. 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. 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. 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
  • 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. 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. VIEWMODEL VAR PHOTOVIEWMODEL = { PHOTOS: KO.OBSERVABLEARRAY([]), FAVORITES: KO.OBSERVABLEARRAY([]), ... };
  • 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. 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. 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. 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. DATA-CLASS BINDING VAR BINDINGS = { RETRIEVEPHOTOS: { SUBMIT: VIEWMODEL.GETPHOTOS }, RENDERPHOTOTEMPLATE : { TEMPLATE: 'PHOTOS-TEMPLATE' } };! ! !
  • 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. 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. 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. THANK YOU TWITTER: @KIANOSHP BLOG: INNOVATORYLIFE.COM PRESENTATION INFO: HTTP://KIANO.SH/RIB8KH

Notas del editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n