building large apps


                rebecca murphey • dojoconf • @rmurphey


Saturday, September 17, 11
A content management system for
         constructing content-rich mobile applications.
         A content publishing system that uses Dojo
         and PhoneGap to create a mobile app from the
         output of the CMS.


Saturday, September 17, 11
Saturday, September 17, 11
Data




                                                                                            Page Controller
                                                                                                               Component


             URL Change      Router                   Route                  Page Factory                      Component
                                                                                                  Capability

                                                                                                               Component



               Device
              Storage




               Remote




                                                       UI




                                                     Browser
                             Page Container
                               Old Page Controller           New Page Controller
                                Component                      Component

                                Component                      Component

                                Component                      Component




Saturday, September 17, 11
e secret to building large apps is
           never build large apps. Break up your
           applications into small pieces. en,
           assemble those testable, bite-sized pieces
           into your big application.
                                            Justin Meyer




Saturday, September 17, 11
Data




                                                                                            Page Controller
                                                                                                               Component


             URL Change      Router                   Route                  Page Factory                      Component
                                                                                                  Capability

                                                                                                               Component



               Device
              Storage




               Remote




                                                       UI




                                                     Browser
                             Page Container
                               Old Page Controller           New Page Controller
                                Component                      Component

                                Component                      Component

                                Component                      Component




Saturday, September 17, 11
Data




                    URL Change   Router   Route




                       Device
                      Storage




                       Remote



Saturday, September 17, 11
Page Controller
                                                Component


           Page Factory                         Component
                                   Capability

                                                Component




Saturday, September 17, 11
UI




                                                    Browser
                             Page Container
                              Old Page Controller          New Page Controller
                                Component                     Component

                                Component                     Component

                                Component                     Component




Saturday, September 17, 11
Data




                    URL Change   Router   Route




                       Device
                      Storage




                       Remote



Saturday, September 17, 11
#/node/123




Saturday, September 17, 11
function nodeRoute(route, nodeId, pageState) {
                  pageState = pageState || {};

                     var nodeModel = toura.app.Data.getModel(nodeId),
                         page = toura.app.UI.getCurrentPage();

                     if (!page || !page.node || nodeId !== page.node.id) {
                       page = toura.app.PageFactory.createPage('node', nodeModel);

                       page.init(pageState);
                       toura.app.UI.showPage(page, nodeModel);
                     } else {
                       page.init(pageState);
                     }
                }




Saturday, September 17, 11
Page Controller
                                                Component


           Page Factory                         Component
                                   Capability

                                                Component




Saturday, September 17, 11
function nodeRoute(route, nodeId, pageState) {
                  pageState = pageState || {};

                     var nodeModel = toura.app.Data.getModel(nodeId),
                         page = toura.app.UI.getCurrentPage();

                     if (!page || !page.node || nodeId !== page.node.id) {
                       page = toura.app.PageFactory.createPage('node', nodeModel);

                       page.init(pageState);
                       toura.app.UI.showPage(page, nodeModel);
                     } else {
                       page.init(pageState);
                     }
                }




Saturday, September 17, 11
Saturday, September 17, 11
this.connect(this.videoList, 'onSelect', function(assetId) {
            var video = this._videoById(assetId);
            this.videoCaption.set('content', video.caption || '');
            this.videoPlayer.play(assetId);
          });




Saturday, September 17, 11
videoPlayer.set('mediaId', mediaId);




                             _setMediaIdAttr : function(mediaId) {
                               var media = this.media = this.mediasCache[mediaId];

                                  if (this.useHtml5Player && !this.player) {
                                    this._queuedMedia = media;
                                    return;
                                  }

                                  this._queuedMedia = null;

                                  if (this.player) {
                                    this.player.src = media.url;
                                  }
                             },



Saturday, September 17, 11
myComponent.set(key, val)
          to change state

          myComponent.on<Evt>(data)
          to announce state changes

          myComponent.subscribe(topic)
          to react to published topics

          dojo.publish(topic, data)
          to announce occurrences of app-wide interest

          myController.connect(component, evt, handler)
          to listen for events & methods



Saturday, September 17, 11
Saturday, September 17, 11
Search Input


                                                           toura.app.Data.search(term)
             searchInputInstance.onSearch(term)




                                            Search Page
                                            Controller          Application Data



    searchResults.set('results', resultSet)
                                                           return resultSet



                                          Search Results
                                             Display




Saturday, September 17, 11
dojo.declare(
            'toura.pageControllers.search.Search',
            [ toura.pageControllers._Page ], {

              // ...

              postCreate : function() {
                // ...
                this.connect(this.searchInput, 'onSearch', '_handleSearch');
              },

              _handleSearch : function(term) {
                if (term === this.lastSearchTerm) { return; }
                this.searchResults.set('results', toura.app.Data.search(term));
              },

            // ...
          });




Saturday, September 17, 11
Page Controller
                                                Component


           Page Factory                         Component
                                   Capability

                                                Component




Saturday, September 17, 11
UI




                                                    Browser
                             Page Container
                              Old Page Controller          New Page Controller
                                Component                     Component

                                Component                     Component

                                Component                     Component




Saturday, September 17, 11
function nodeRoute(route, nodeId, pageState) {
                  pageState = pageState || {};

                     var nodeModel = toura.app.Data.getModel(nodeId),
                         page = toura.app.UI.getCurrentPage();

                     if (!page || !page.node || nodeId !== page.node.id) {
                       page = toura.app.PageFactory.createPage('node', nodeModel);

                       page.init(pageState);
                       toura.app.UI.showPage(page, nodeModel);
                     } else {
                       page.init(pageState);
                     }
                }




Saturday, September 17, 11
showPage : function(page, node) {
                        if (page.startup) {
                          var s = dojo.subscribe('/page/transition/end', function() {
                            page.startup();
                            dojo.unsubscribe(s);
                          });
                        }

                             this.containers.pages.set('content', page);
                             this.currentPage = page;
                      }




Saturday, September 17, 11
Saturday, September 17, 11
http://toura.github.com/mulberry
                @touradev




                             rebeccamurphey.com • blog.rebeccamurphey.com • @rmurphey




Saturday, September 17, 11

DojoConf: Building Large Apps

  • 1.
    building large apps rebecca murphey • dojoconf • @rmurphey Saturday, September 17, 11
  • 2.
    A content managementsystem for constructing content-rich mobile applications. A content publishing system that uses Dojo and PhoneGap to create a mobile app from the output of the CMS. Saturday, September 17, 11
  • 3.
  • 4.
    Data Page Controller Component URL Change Router Route Page Factory Component Capability Component Device Storage Remote UI Browser Page Container Old Page Controller New Page Controller Component Component Component Component Component Component Saturday, September 17, 11
  • 5.
    e secret tobuilding large apps is never build large apps. Break up your applications into small pieces. en, assemble those testable, bite-sized pieces into your big application. Justin Meyer Saturday, September 17, 11
  • 6.
    Data Page Controller Component URL Change Router Route Page Factory Component Capability Component Device Storage Remote UI Browser Page Container Old Page Controller New Page Controller Component Component Component Component Component Component Saturday, September 17, 11
  • 7.
    Data URL Change Router Route Device Storage Remote Saturday, September 17, 11
  • 8.
    Page Controller Component Page Factory Component Capability Component Saturday, September 17, 11
  • 9.
    UI Browser Page Container Old Page Controller New Page Controller Component Component Component Component Component Component Saturday, September 17, 11
  • 10.
    Data URL Change Router Route Device Storage Remote Saturday, September 17, 11
  • 11.
  • 12.
    function nodeRoute(route, nodeId,pageState) { pageState = pageState || {}; var nodeModel = toura.app.Data.getModel(nodeId), page = toura.app.UI.getCurrentPage(); if (!page || !page.node || nodeId !== page.node.id) { page = toura.app.PageFactory.createPage('node', nodeModel); page.init(pageState); toura.app.UI.showPage(page, nodeModel); } else { page.init(pageState); } } Saturday, September 17, 11
  • 13.
    Page Controller Component Page Factory Component Capability Component Saturday, September 17, 11
  • 14.
    function nodeRoute(route, nodeId,pageState) { pageState = pageState || {}; var nodeModel = toura.app.Data.getModel(nodeId), page = toura.app.UI.getCurrentPage(); if (!page || !page.node || nodeId !== page.node.id) { page = toura.app.PageFactory.createPage('node', nodeModel); page.init(pageState); toura.app.UI.showPage(page, nodeModel); } else { page.init(pageState); } } Saturday, September 17, 11
  • 15.
  • 16.
    this.connect(this.videoList, 'onSelect', function(assetId){ var video = this._videoById(assetId); this.videoCaption.set('content', video.caption || ''); this.videoPlayer.play(assetId); }); Saturday, September 17, 11
  • 17.
    videoPlayer.set('mediaId', mediaId); _setMediaIdAttr : function(mediaId) { var media = this.media = this.mediasCache[mediaId]; if (this.useHtml5Player && !this.player) { this._queuedMedia = media; return; } this._queuedMedia = null; if (this.player) { this.player.src = media.url; } }, Saturday, September 17, 11
  • 18.
    myComponent.set(key, val) to change state myComponent.on<Evt>(data) to announce state changes myComponent.subscribe(topic) to react to published topics dojo.publish(topic, data) to announce occurrences of app-wide interest myController.connect(component, evt, handler) to listen for events & methods Saturday, September 17, 11
  • 19.
  • 20.
    Search Input toura.app.Data.search(term) searchInputInstance.onSearch(term) Search Page Controller Application Data searchResults.set('results', resultSet) return resultSet Search Results Display Saturday, September 17, 11
  • 21.
    dojo.declare( 'toura.pageControllers.search.Search', [ toura.pageControllers._Page ], { // ... postCreate : function() { // ... this.connect(this.searchInput, 'onSearch', '_handleSearch'); }, _handleSearch : function(term) { if (term === this.lastSearchTerm) { return; } this.searchResults.set('results', toura.app.Data.search(term)); }, // ... }); Saturday, September 17, 11
  • 22.
    Page Controller Component Page Factory Component Capability Component Saturday, September 17, 11
  • 23.
    UI Browser Page Container Old Page Controller New Page Controller Component Component Component Component Component Component Saturday, September 17, 11
  • 24.
    function nodeRoute(route, nodeId,pageState) { pageState = pageState || {}; var nodeModel = toura.app.Data.getModel(nodeId), page = toura.app.UI.getCurrentPage(); if (!page || !page.node || nodeId !== page.node.id) { page = toura.app.PageFactory.createPage('node', nodeModel); page.init(pageState); toura.app.UI.showPage(page, nodeModel); } else { page.init(pageState); } } Saturday, September 17, 11
  • 25.
    showPage : function(page,node) { if (page.startup) { var s = dojo.subscribe('/page/transition/end', function() { page.startup(); dojo.unsubscribe(s); }); } this.containers.pages.set('content', page); this.currentPage = page; } Saturday, September 17, 11
  • 26.
  • 27.
    http://toura.github.com/mulberry @touradev rebeccamurphey.com • blog.rebeccamurphey.com • @rmurphey Saturday, September 17, 11