SlideShare une entreprise Scribd logo
1  sur  83
Stefan Scheidt
      OPITZ CONSULTING GmbH

         Entwurfsmuster für
mobile JavaScript-Web-Apps
Entwurfsmuster für mobile
   JavaScript-Web-Apps
        Stefan Scheidt
   OPITZ CONSULTING GmbH
Wer bin ich?



stefan.scheidt@opitz-consulting.com
          (@stefanscheidt)
Mission                                          Märkte
Wir entwickeln gemeinsam mit allen                Branchenübergreifend
Branchen Lösungen, die dazu führen, dass          Über 600 Kunden
sich diese Organisationen besser entwickeln                                           29%
als ihr Wettbewerb.                                                29%
                                                                                      Handel / Logistik /
                                                                                      Dienstleistungen
                                                 Industrie / Versorger /
Unsere Dienstleistung erfolgt                      Telekommunikation
partnerschaftlich und ist auf eine langjährige                                 42%
Zusammenarbeit angelegt.                                                       Öffentliche Auftraggeber / Banken und
                                                                               Versicherungen / Vereine und Verbände



Leistungsangebot                                 Eckdaten
 Business IT Alignment                           Gründung 1990
 Business Information Management                 400 Mitarbeiter
 Business Process Management                     8 Standorte
 Anwendungsentwicklung
 SOA und System-Integration
 IT-Infrastruktur-Management


                                                                           © OPITZ CONSULTING GmbH 2012         Seite 4
Wer sind Sie?
In diesem Vortrag geht‘s um ...

     ... die Entwicklung
 testbarer und wartbarer
mobiler JavaScript Web-Apps
In diesem Vortrag geht‘s um ...

     ... die Entwicklung
 testbarer und wartbarer
mobiler JavaScript Web-Apps
In diesem Vortrag geht‘s um ...

     ... die Entwicklung
 testbarer und wartbarer
mobiler JavaScript Web-Apps
Die Beispiel-App ...

http://tigbro.github.com/todo-mobile
https://github.com/tigbro/todo-mobile
Architektur
"Multi Page Web App"

Browser                             Server


           HTML-Page
                        Model
                         View       Data     Backend
           UI Values   Controller
"AJAX Web App"

Browser                         Server


          Change    Model
AJAX-                View                Ba
                                Data
Engine             Controller
          Events
"Single Page Web App"

  Browser             Server


   Model
    View       Data   Backend
  Controller
Komponenten-Bibliotheken
jQuery Mobile




 http://jquerymobile.com/
Die Beispiel-App
<div id="main" data-role="page">
  <div data-role="header">
    <h1>Todos</h1>
    <a href="">Save</a>
    <a href="#settings">Settings</a>
  </div>
  <div data-role="content">
    <div data-role="fieldcontain">
       <form data-ajax="false">
         <input type="text">
       </form>
    </div>
    <fieldset data-role="controlgroup">
       <input type="checkbox" id="todo1"/>
       <label for="todo1">create a mobile todo app</label>
    </fieldset>
  </div>
</div>
                                                 jQuery Mobile Markup
<div id="main" data-role="page">
  <div data-role="header">
    <h1>Todos</h1>
    <a href="">Save</a>
    <a href="#settings">Settings</a>
  </div>
  <div data-role="content">
    <div data-role="fieldcontain">
       <form data-ajax="false">
         <input type="text">
       </form>
    </div>
    <fieldset data-role="controlgroup">
       <input type="checkbox" id="todo1"/>
       <label for="todo1">create a mobile todo app</label>
    </fieldset>
  </div>
</div>
                                                 jQuery Mobile Markup
<div id="main" data-role="page">
  <div data-role="header">
    <h1>Todos</h1>
    <a href="">Save</a>
    <a href="#settings">Settings</a>
  </div>
  <div data-role="content">
    <div data-role="fieldcontain">
       <form data-ajax="false">
         <input type="text">
       </form>
    </div>
    <fieldset data-role="controlgroup">
       <input type="checkbox" id="todo1"/>
       <label for="todo1">create a mobile todo app</label>
    </fieldset>
  </div>
</div>
                                                 jQuery Mobile Markup
<div id="main" data-role="page">
  <div data-role="header">
    <h1>Todos</h1>
    <a href="">Save</a>
    <a href="#settings">Settings</a>
  </div>
  <div data-role="content">
    <div data-role="fieldcontain">
       <form data-ajax="false">
         <input type="text">
       </form>
    </div>
    <fieldset data-role="controlgroup">
       <input type="checkbox" id="todo1"/>
       <label for="todo1">create a mobile todo app</label>
    </fieldset>
  </div>
</div>
                                                 jQuery Mobile Markup
<div id="main" data-role="page">
  <div data-role="header">
    <h1>Todos</h1>
    <a href="">Save</a>
    <a href="#settings">Settings</a>
  </div>
  <div data-role="content">
    <div data-role="fieldcontain">
       <form data-ajax="false">
         <input type="text">
       </form>
    </div>
    <fieldset data-role="controlgroup">
       <input type="checkbox" id="todo1"/>
       <label for="todo1">create a mobile todo app</label>
    </fieldset>
  </div>
</div>
                                                 jQuery Mobile Markup
DOM-Transformation
durch jQuery-Mobile
<input type="checkbox" id="todo1"/>
<label for="todo1">create a mobile todo app</label>



<div class="ui-checkbox">
  <input type="checkbox" name="todo.done" id="todo1">
  <label class="ui-btn ui-btn-up-c ui-btn-icon-left
                 ui-btn-corner-all ui-checkbox-off"
          for="todo1" data-theme="c">
    <span class="ui-btn-inner ui-btn-corner-all">
       <span class="ui-btn-text">create a mobile todo app</span>
       <span class="ui-icon ui-icon-checkbox-off
                    ui-icon-shadow"></span>
    </span>
  </label>
</div>

                                     jQuery Mobile Markup Transformation
<input type="checkbox" id="todo1"/>
<label for="todo1">create a mobile todo app</label>



<div class="ui-checkbox">
  <input type="checkbox" name="todo.done" id="todo1">
  <label class="ui-btn ui-btn-up-c ui-btn-icon-left
                 ui-btn-corner-all ui-checkbox-off"
          for="todo1" data-theme="c">
    <span class="ui-btn-inner ui-btn-corner-all">
       <span class="ui-btn-text">create a mobile todo app</span>
       <span class="ui-icon ui-icon-checkbox-off
                    ui-icon-shadow"></span>
    </span>
  </label>
</div>

                                     jQuery Mobile Markup Transformation
Two Way Data Binding
Manuelles Binding
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
$('#addTodo').submit(function(event) {
    addTodo();
    event.preventDefault();
});

function addTodo() {
    var inputText = $('#inputText').val();
    var list = $('#todos');
    var entryCount = list.find('input').length;
    list.append(entryTemplate(entryCount, inputText));
    list.trigger('create');
    $('#inputText').val('');
}

function entryTemplate(index, name) {
    var id = 'todo' + index;
    return '<input type="checkbox" id="' + id + '"/>' +
           '<label for="' + id + '">' + name + '</label>';
}
Das Ziel sollte aber sein:

   function TodoController() {
       this.todos = [];
       this.inputText = '';
       this.addTodo = function() {
           this.todos.push({
               name: this.inputText,
               done: false
           });
           this.inputText = '';
       };
   }
Angular JS

Declarative                       MVC with
UI Templates                      Dependency Injection




Two-Way                           Framework
Data Binding




        http://angularjs.org/#/
Two-Way Databinding


       read              read
       write    Data-    write
DOM                              Controller
               binding
       watch             watch
Scopes
                               Scope
                                        Expressions
       $get(<expr>)
                                        'inputText'

                                       'todos.length'
  $set(<expr>, <value>)
                                            ...



$watch(<expr>, <callback>)
Demo
Das Ziel ...
function TodoController() {
    this.todos = [];
    this.inputText = '';
    this.addTodo = function() {
        this.todos.push({
            name: this.inputText,
            done: false
        });
        this.inputText = '';
    };
}
Mit Angular ...
function TodoController($scope) {
    $scope.todos = [];
    $scope.inputText = '';
    $scope.addTodo = function() {
        $scope.todos.push({
            name: $scope.inputText,
            done: false
        });
        $scope.inputText = '';
    };
}
TodoController.$inject = ['$scope'];
<div data-role="page"                      TodoController-Scope
     ng:controller="TodoController">
                                           inputText: 'new todo'
                            erzeugt
  <input type="text"                       todos: [...]
         name="inputText"
                              bindet
                                      bindet
  <div ng:repeat="todo in todos">

                    erzeugt                           Repeater Scope
                                                     Repeater Scope
                                                    Repeater Scope
                                            todo: {
                                             todo:
                                           todo: { {
      <input type="checkbox"
             value="todo.done"/>                      done: false
                                                     done: false
                                                    done: false
                                 bindet
                                                      name: 'makemoney'
                                                     name: 'makemoney'
                                                    name: 'makemoney'
      <label>
        {{todo.name}}                           }
      </label>
                              bindet       }}
jQuery Mobile und AngularJS

        Das Problem:

   Die DOM-Manipulationen von
   jQuery Mobile und AngularJS
   müssen koordiniert werden!
jQuery Mobile und AngularJS

         Die Lösung:


jQuery Mobile Angular Adapter
jQuery Mobile Angular Adapter

Koordination von jQuery Mobile und AngularJS

    Erweiterungen für mobile Web-Apps

             Open Source unter
         https://github.com/tigbro/
       jquery-mobile-angular-adapter
Dependency Injection
Dependency Injection ist ein Entwurfsmuster
 und dient dazu, die Abhängigkeiten zwischen
        Komponenten zu minimieren.


    Es überträgt die Verantwortung für das
Erzeugen und die Verknüpfung von Objekten an
    ein extern konfigurierbares Framework


                   http://de.wikipedia.org/wiki/Dependency_Injection
Dependency Injection ist ein Entwurfsmuster
 und dient dazu, die Abhängigkeiten zwischen
        Komponenten zu minimieren.


    Es überträgt die Verantwortung für das
Erzeugen und die Verknüpfung von Objekten an
    ein extern konfigurierbares Framework


                   http://de.wikipedia.org/wiki/Dependency_Injection
Beispiel: Backend-Anbindung

 function refreshTodos() {
     var self = this;
     read('ToDoApp', function(response) {
         self.todos = response;
     });
 }
Beispiel: Backend-Anbindung

 function refreshTodos() {
     var self = this;
     read('ToDoApp', function(response) {
         self.todos = response;
     });
 }
Beispiel: Backend-Anbindung

 var readUrl = 'https://secure.openkeyval.org/';

 function read(key, success) {
     var url = readUrl + key;
     waitdialog.show();
     jsonp(url, function(data) {
         success(data);
         waitdialog.hide();
     });
 }
Beispiel: Backend-Anbindung

 var readUrl = 'https://secure.openkeyval.org/';

 function read(key, success) {
     var url = readUrl + key;
     waitdialog.show();
     jsonp(url, function(data) {
         success(data);
         waitdialog.hide();
     });
 }
Beispiel: Backend-Anbindung

 var readUrl = 'https://secure.openkeyval.org/';

 function read(key, success) {
     var url = readUrl + key;
     waitdialog.show();
     jsonp(url, function(data) {
         success(data);
         waitdialog.hide();
     });
 }
Beispiel: Backend-Anbindung

                                                   waitDialog
todoController           todoStore                 key     value
key              value   key          value        ...     ...
refreshTodos ...         read         ...
todoStore                waitDialog
                         jsonp                     jsonp
                                                   key     value
                                                   ...     ...

                                      created by
                                       Factories
Beispiel: Backend-Anbindung

                                                  waitDialog
todoController               todoStore            key     value
key              value       key          value   ...     ...
refreshTodos ...             read         ...
todoStore                    waitDialog
                             jsonp                jsonp
                                                  key     value
                                                  ...     ...
                             created by
                         Dependency Injection
Angular JS

Declarative                       MVC with
UI Templates                      Dependency Injection




Two-Way                           Framework
Data Binding




        http://angularjs.org/#/
Services und DI mit Angular
function jsonpFactory() {
  // returns jsonp function
  // ...
}
function waitdialogFactory() {
  // returns waitdialog object
  // ...
}
Services und DI mit Angular
var module = angular.module("todo", []);
Services und DI mit Angular
var module = angular.module("todo", []);
module.factory('jsonp', jsonpFactory);
module.factory('waitdialog', waitdialogFactory);
Services und DI mit Angular
var module = angular.module("todo", []);
module.factory('jsonp', jsonpFactory);
module.factory('waitdialog', waitdialogFactory);

function todoStoreFactory(jsonp, waitdialog) {
    function read(key, success) {
        // use jsonp, waitdialog here
    }
    return {
        read: read
    };
}
Services und DI mit Angular
var module = angular.module("todo", []);
module.factory('jsonp', jsonpFactory);
module.factory('waitdialog', waitdialogFactory);

function todoStoreFactory(jsonp, waitdialog) {
    function read(key, success) {
        // use jsonp, waitdialog here
    }
    return {
        read: read
    };
}
todoStoreFactory.$inject = ['jsonp', 'waitdialog'];
Services und DI mit Angular
var module = angular.module("todo", []);
module.factory('jsonp', jsonpFactory);
module.factory('waitdialog', waitdialogFactory);

function todoStoreFactory(jsonp, waitdialog) {
    // ...
}
todoStoreFactory.$inject = ['jsonp', 'waitdialog'];

module.factory('todoStore', todoStoreFactory);
Controller und DI mit Angular

function TodoController($scope, todoStore) {
  ...
}
TodoController.$inject = ['$scope', 'todoStore'];

module.controller("rylc.TodoController", TodoController);
Controller und DI mit Angular

function TodoController($scope, todoStore) {
  ...
}
TodoController.$inject = ['$scope', 'todoStore'];

module.controller("rylc.TodoController", TodoController);
Controller und DI mit Angular

function TodoController($scope, todoStore) {
  ...
}
TodoController.$inject = ['$scope', 'todoStore'];

module.controller("rylc.TodoController", TodoController);
jQuery Mobile Angular Adapter

Koordination von jQuery Mobile und AngularJS

    Erweiterungen für mobile Web-Apps

             Open Source unter
         https://github.com/tigbro/
       jquery-mobile-angular-adapter
jQuery Mobile Angular Adapter



       Mobile Events
<div id="main" data-role="page"
     ng:controller="TodoController"
     ngm:pagebeforeshow="refreshTodos()">
        ...
</div>


           Unterstütze Events:

      click               swipe
      pagebeforeshow      swiperight
      pageshow            swipeleft
      pagebeforehide      tap
      pagehide            taphold
jQuery Mobile Angular Adapter



      Shared Controller
LoginPage
<div id="loginPage"                        Scope
     ng-controller="LoginController">
                                        login

  <a ngm:click="login()">
LoginPage
<div id="loginPage"                        Scope
     ng-controller="LoginController">
                                        login

  <a ngm-click="login()">

<div id="welcomePage"                   WelcomePage
     ng-controller="WelcomeController">    Scope

                                        logout

  <a ngm-click="logout()">
LoginPage
<div id="loginPage"                        Scope
     ngm-shared-controller=
                                                      Authentication-
     "auth:AuthenticationController">   auth          Controller Scope
  <a ngm-click="login()">
                                                      login
                                                      logout
<div id="welcomePage"                   WelcomePage
     ngm-shared-controller=                Scope
     "auth:AuthenticationController">
                                        auth
  <a ngm-click="logout()">
LoginPage
<div id="loginPage"                        Scope
     ngm-shared-controller=
                                                      Authentication-
     "auth:AuthenticationController">   auth          Controller Scope
  <a ngm-click="auth.login()">
                                                      login
                                                      logout
<div id="welcomePage"                   WelcomePage
     ngm-shared-controller=                Scope
     "auth:AuthenticationController">
                                        auth
  <a ngm-click="auth.logout()">
jQuery Mobile Angular Adapter



         Wait Dialog
waitDialog.show('loading');

waitDialog.hide();




waitDialog.show('click to abort',
       onClickCallback);
Fazit


     Auch bei der Entwicklung
      von JavaScript Clients
sollten geeignete Entwurfsmuster
       angewendet werden!
Fazit



Bibliotheken und Frameworks
  helfen bei der Umsetzung!
Fazit

Eine praxiserprobte Kombination für die
    Entwicklung mobiler Web-Apps:

            jQuery Mobile
              + AngularJS
   + jQuery Mobile Angular Adapter
In the hive 11: nectar and pollen
      by Max xx, http://www.flickr.com/photos/max_westby/4567762490

                                     Books
By Rodrigo Galindez, http://www.flickr.com/photos/rodrigogalindez/4637637337/

                              IMG_1300-Edit
  by Susan E Adams, http://www.flickr.com/photos/susanad813/3912914836/

                                  Doble Via
     by amslerPIX, http://www.flickr.com/photos/amslerpix/6242266697/

                            MacBook Pro Keyboard
by superstrikertwo, http://www.flickr.com/photos/superstrikertwo/4989727256/

                            Stubborn Last Drop
  by RogueSun Media, http://www.flickr.com/photos/shuttercat7/627798443/
Vielen Dank
für Ihr Interesse!
  @stefanscheidt
www.opitz-consulting.com/go_mobile

Contenu connexe

Tendances

Max Pronko - Best practices for checkout customisation in Magento 2
Max Pronko - Best practices for checkout customisation in Magento 2Max Pronko - Best practices for checkout customisation in Magento 2
Max Pronko - Best practices for checkout customisation in Magento 2Meet Magento Italy
 
New text document (2) 2
New text document (2) 2New text document (2) 2
New text document (2) 2raj lex
 
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...irwinvifxcfesre
 
Intro to jQuery UI
Intro to jQuery UIIntro to jQuery UI
Intro to jQuery UIappendTo
 
City bars workshop
City bars workshopCity bars workshop
City bars workshopJames Pearce
 
Check out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro showCheck out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro showchicagonewsyesterday
 
Here's the Downtown Sound lineup for 2015
Here's the Downtown Sound lineup for 2015Here's the Downtown Sound lineup for 2015
Here's the Downtown Sound lineup for 2015chicagonewsyesterday
 

Tendances (9)

Max Pronko - Best practices for checkout customisation in Magento 2
Max Pronko - Best practices for checkout customisation in Magento 2Max Pronko - Best practices for checkout customisation in Magento 2
Max Pronko - Best practices for checkout customisation in Magento 2
 
New text document (2) 2
New text document (2) 2New text document (2) 2
New text document (2) 2
 
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
Peek inside the fantastical Ukrainian Village home and studio of artists Jare...
 
Intro to jQuery UI
Intro to jQuery UIIntro to jQuery UI
Intro to jQuery UI
 
City bars workshop
City bars workshopCity bars workshop
City bars workshop
 
Check out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro showCheck out our photos of the Pixies' Metro show
Check out our photos of the Pixies' Metro show
 
Get more votes!
Get more votes!Get more votes!
Get more votes!
 
Here's the Downtown Sound lineup for 2015
Here's the Downtown Sound lineup for 2015Here's the Downtown Sound lineup for 2015
Here's the Downtown Sound lineup for 2015
 
Web components v1 intro
Web components v1 introWeb components v1 intro
Web components v1 intro
 

En vedette (20)

Vegan Magazine
Vegan MagazineVegan Magazine
Vegan Magazine
 
RETAIL MANAGEMENT
RETAIL MANAGEMENTRETAIL MANAGEMENT
RETAIL MANAGEMENT
 
Log splitter under $500
Log splitter under $500Log splitter under $500
Log splitter under $500
 
Gartner EEE - Bilgi Yönetimi 2012 - TTNET sunumu
Gartner EEE - Bilgi Yönetimi 2012 - TTNET sunumuGartner EEE - Bilgi Yönetimi 2012 - TTNET sunumu
Gartner EEE - Bilgi Yönetimi 2012 - TTNET sunumu
 
咕子爸B
咕子爸B咕子爸B
咕子爸B
 
เรียนรู้ Wrodpress
เรียนรู้ Wrodpressเรียนรู้ Wrodpress
เรียนรู้ Wrodpress
 
Ramsplitter 20 ton horiz vert elec log splitter
Ramsplitter 20 ton horiz vert elec log splitterRamsplitter 20 ton horiz vert elec log splitter
Ramsplitter 20 ton horiz vert elec log splitter
 
Proximal Biceps
Proximal BicepsProximal Biceps
Proximal Biceps
 
Motivazioni
MotivazioniMotivazioni
Motivazioni
 
Урок 5 ФГОС нового поколения
Урок 5 ФГОС нового поколенияУрок 5 ФГОС нового поколения
Урок 5 ФГОС нового поколения
 
Biología ii u3
Biología ii u3Biología ii u3
Biología ii u3
 
Salud y ambiente
Salud y ambienteSalud y ambiente
Salud y ambiente
 
Portfolio- Gabriella Santana
Portfolio- Gabriella SantanaPortfolio- Gabriella Santana
Portfolio- Gabriella Santana
 
Extra-cellular Matrix Patches
Extra-cellular Matrix PatchesExtra-cellular Matrix Patches
Extra-cellular Matrix Patches
 
Force log splitter
Force log splitterForce log splitter
Force log splitter
 
5 ton log splitters
5 ton log splitters5 ton log splitters
5 ton log splitters
 
poster
posterposter
poster
 
Reforma educativa marzo-marzo
Reforma educativa marzo-marzoReforma educativa marzo-marzo
Reforma educativa marzo-marzo
 
Gas log splitters
Gas log splittersGas log splitters
Gas log splitters
 
AC Separations
AC SeparationsAC Separations
AC Separations
 

Plus de OPITZ CONSULTING Deutschland

Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"OPITZ CONSULTING Deutschland
 
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der PraxisOC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der PraxisOPITZ CONSULTING Deutschland
 
OC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
OC|Webcast: Oracle Lizenzierung - Virtualisierung und CloudOC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
OC|Webcast: Oracle Lizenzierung - Virtualisierung und CloudOPITZ CONSULTING Deutschland
 
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!OPITZ CONSULTING Deutschland
 
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...OPITZ CONSULTING Deutschland
 
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...OPITZ CONSULTING Deutschland
 
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?OPITZ CONSULTING Deutschland
 
OC|Weekly Talk - Digitales Coaching & Smart Sparring
OC|Weekly Talk - Digitales Coaching & Smart Sparring OC|Weekly Talk - Digitales Coaching & Smart Sparring
OC|Weekly Talk - Digitales Coaching & Smart Sparring OPITZ CONSULTING Deutschland
 
Effiziente Betriebsoptimierung durch Cloud Nutzung
Effiziente Betriebsoptimierung durch Cloud NutzungEffiziente Betriebsoptimierung durch Cloud Nutzung
Effiziente Betriebsoptimierung durch Cloud NutzungOPITZ CONSULTING Deutschland
 

Plus de OPITZ CONSULTING Deutschland (20)

OC|Webcast: Grundlagen der Oracle Lizenzierung
OC|Webcast: Grundlagen der Oracle LizenzierungOC|Webcast: Grundlagen der Oracle Lizenzierung
OC|Webcast: Grundlagen der Oracle Lizenzierung
 
OC|Webcast "Java heute" vom 28.09.2021
OC|Webcast "Java heute" vom 28.09.2021OC|Webcast "Java heute" vom 28.09.2021
OC|Webcast "Java heute" vom 28.09.2021
 
OC|Webcast "Java heute" vom 24.08.2021
OC|Webcast "Java heute" vom 24.08.2021OC|Webcast "Java heute" vom 24.08.2021
OC|Webcast "Java heute" vom 24.08.2021
 
OC|Webcast "Daten wirklich nutzen"
OC|Webcast "Daten wirklich nutzen"OC|Webcast "Daten wirklich nutzen"
OC|Webcast "Daten wirklich nutzen"
 
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
Architecture Room Stuttgart - "Cloud-native ist nur ein Teil des Spiels!"
 
OC|Webcast "Willkommen in der Cloud!"
OC|Webcast "Willkommen in der Cloud!"OC|Webcast "Willkommen in der Cloud!"
OC|Webcast "Willkommen in der Cloud!"
 
OC|Webcast "Die neue Welt der Virtualisierung"
OC|Webcast "Die neue Welt der Virtualisierung"OC|Webcast "Die neue Welt der Virtualisierung"
OC|Webcast "Die neue Welt der Virtualisierung"
 
10 Thesen zur professionellen Softwareentwicklung
10 Thesen zur professionellen Softwareentwicklung10 Thesen zur professionellen Softwareentwicklung
10 Thesen zur professionellen Softwareentwicklung
 
OC|Webcast: Oracle Lizenzierung - Lizenznews 2021
OC|Webcast: Oracle Lizenzierung - Lizenznews 2021OC|Webcast: Oracle Lizenzierung - Lizenznews 2021
OC|Webcast: Oracle Lizenzierung - Lizenznews 2021
 
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der PraxisOC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
OC|Webcast: Oracle Lizenzierung - Die größten Fallen in der Praxis
 
OC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
OC|Webcast: Oracle Lizenzierung - Virtualisierung und CloudOC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
OC|Webcast: Oracle Lizenzierung - Virtualisierung und Cloud
 
OC|Webcast: Grundlagen der Oracle-Lizenzierung
OC|Webcast: Grundlagen der Oracle-LizenzierungOC|Webcast: Grundlagen der Oracle-Lizenzierung
OC|Webcast: Grundlagen der Oracle-Lizenzierung
 
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
OC|Weekly Talk: Inspect’n’Adapt – Make Change come true!
 
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
OC|Webcast: Schnell und clever in die AWS Cloud – Migrationsszenarien und Han...
 
OC|Weekly Talk The Power of DevOps…
OC|Weekly Talk  The Power of DevOps…OC|Weekly Talk  The Power of DevOps…
OC|Weekly Talk The Power of DevOps…
 
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
OC|Weekly Talk: "Das müsste man mal digitalisieren" - Mit Low-Code schnell zu...
 
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
OC|Weekly Talk: Service Management – Was hat sich durch Corona geändert?
 
OC|Weekly Talk - Digitales Coaching & Smart Sparring
OC|Weekly Talk - Digitales Coaching & Smart Sparring OC|Weekly Talk - Digitales Coaching & Smart Sparring
OC|Weekly Talk - Digitales Coaching & Smart Sparring
 
OC|Weekly Talk - Beratung remote
OC|Weekly Talk - Beratung remoteOC|Weekly Talk - Beratung remote
OC|Weekly Talk - Beratung remote
 
Effiziente Betriebsoptimierung durch Cloud Nutzung
Effiziente Betriebsoptimierung durch Cloud NutzungEffiziente Betriebsoptimierung durch Cloud Nutzung
Effiziente Betriebsoptimierung durch Cloud Nutzung
 

Entwurfsmuster für mobile JavaScript-Web-Apps – Mobile Tech Conference 2012 Autumn – Stefan Scheidt

  • 1. Stefan Scheidt OPITZ CONSULTING GmbH Entwurfsmuster für mobile JavaScript-Web-Apps
  • 2. Entwurfsmuster für mobile JavaScript-Web-Apps Stefan Scheidt OPITZ CONSULTING GmbH
  • 4. Mission Märkte Wir entwickeln gemeinsam mit allen  Branchenübergreifend Branchen Lösungen, die dazu führen, dass  Über 600 Kunden sich diese Organisationen besser entwickeln 29% als ihr Wettbewerb. 29% Handel / Logistik / Dienstleistungen Industrie / Versorger / Unsere Dienstleistung erfolgt Telekommunikation partnerschaftlich und ist auf eine langjährige 42% Zusammenarbeit angelegt. Öffentliche Auftraggeber / Banken und Versicherungen / Vereine und Verbände Leistungsangebot Eckdaten  Business IT Alignment  Gründung 1990  Business Information Management  400 Mitarbeiter  Business Process Management  8 Standorte  Anwendungsentwicklung  SOA und System-Integration  IT-Infrastruktur-Management © OPITZ CONSULTING GmbH 2012 Seite 4
  • 5.
  • 7. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarer mobiler JavaScript Web-Apps
  • 8. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarer mobiler JavaScript Web-Apps
  • 9. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarer mobiler JavaScript Web-Apps
  • 11.
  • 13. "Multi Page Web App" Browser Server HTML-Page Model View Data Backend UI Values Controller
  • 14. "AJAX Web App" Browser Server Change Model AJAX- View Ba Data Engine Controller Events
  • 15. "Single Page Web App" Browser Server Model View Data Backend Controller
  • 19. <div id="main" data-role="page"> <div data-role="header"> <h1>Todos</h1> <a href="">Save</a> <a href="#settings">Settings</a> </div> <div data-role="content"> <div data-role="fieldcontain"> <form data-ajax="false"> <input type="text"> </form> </div> <fieldset data-role="controlgroup"> <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> </fieldset> </div> </div> jQuery Mobile Markup
  • 20. <div id="main" data-role="page"> <div data-role="header"> <h1>Todos</h1> <a href="">Save</a> <a href="#settings">Settings</a> </div> <div data-role="content"> <div data-role="fieldcontain"> <form data-ajax="false"> <input type="text"> </form> </div> <fieldset data-role="controlgroup"> <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> </fieldset> </div> </div> jQuery Mobile Markup
  • 21. <div id="main" data-role="page"> <div data-role="header"> <h1>Todos</h1> <a href="">Save</a> <a href="#settings">Settings</a> </div> <div data-role="content"> <div data-role="fieldcontain"> <form data-ajax="false"> <input type="text"> </form> </div> <fieldset data-role="controlgroup"> <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> </fieldset> </div> </div> jQuery Mobile Markup
  • 22. <div id="main" data-role="page"> <div data-role="header"> <h1>Todos</h1> <a href="">Save</a> <a href="#settings">Settings</a> </div> <div data-role="content"> <div data-role="fieldcontain"> <form data-ajax="false"> <input type="text"> </form> </div> <fieldset data-role="controlgroup"> <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> </fieldset> </div> </div> jQuery Mobile Markup
  • 23. <div id="main" data-role="page"> <div data-role="header"> <h1>Todos</h1> <a href="">Save</a> <a href="#settings">Settings</a> </div> <div data-role="content"> <div data-role="fieldcontain"> <form data-ajax="false"> <input type="text"> </form> </div> <fieldset data-role="controlgroup"> <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> </fieldset> </div> </div> jQuery Mobile Markup
  • 25. <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> <div class="ui-checkbox"> <input type="checkbox" name="todo.done" id="todo1"> <label class="ui-btn ui-btn-up-c ui-btn-icon-left ui-btn-corner-all ui-checkbox-off" for="todo1" data-theme="c"> <span class="ui-btn-inner ui-btn-corner-all"> <span class="ui-btn-text">create a mobile todo app</span> <span class="ui-icon ui-icon-checkbox-off ui-icon-shadow"></span> </span> </label> </div> jQuery Mobile Markup Transformation
  • 26. <input type="checkbox" id="todo1"/> <label for="todo1">create a mobile todo app</label> <div class="ui-checkbox"> <input type="checkbox" name="todo.done" id="todo1"> <label class="ui-btn ui-btn-up-c ui-btn-icon-left ui-btn-corner-all ui-checkbox-off" for="todo1" data-theme="c"> <span class="ui-btn-inner ui-btn-corner-all"> <span class="ui-btn-text">create a mobile todo app</span> <span class="ui-icon ui-icon-checkbox-off ui-icon-shadow"></span> </span> </label> </div> jQuery Mobile Markup Transformation
  • 27. Two Way Data Binding
  • 29. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 30. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 31. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 32. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 33. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 34. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 35. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 36. $('#addTodo').submit(function(event) { addTodo(); event.preventDefault(); }); function addTodo() { var inputText = $('#inputText').val(); var list = $('#todos'); var entryCount = list.find('input').length; list.append(entryTemplate(entryCount, inputText)); list.trigger('create'); $('#inputText').val(''); } function entryTemplate(index, name) { var id = 'todo' + index; return '<input type="checkbox" id="' + id + '"/>' + '<label for="' + id + '">' + name + '</label>'; }
  • 37. Das Ziel sollte aber sein: function TodoController() { this.todos = []; this.inputText = ''; this.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ''; }; }
  • 38. Angular JS Declarative MVC with UI Templates Dependency Injection Two-Way Framework Data Binding http://angularjs.org/#/
  • 39. Two-Way Databinding read read write Data- write DOM Controller binding watch watch
  • 40. Scopes Scope Expressions $get(<expr>) 'inputText' 'todos.length' $set(<expr>, <value>) ... $watch(<expr>, <callback>)
  • 41. Demo
  • 42. Das Ziel ... function TodoController() { this.todos = []; this.inputText = ''; this.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ''; }; }
  • 43. Mit Angular ... function TodoController($scope) { $scope.todos = []; $scope.inputText = ''; $scope.addTodo = function() { $scope.todos.push({ name: $scope.inputText, done: false }); $scope.inputText = ''; }; } TodoController.$inject = ['$scope'];
  • 44. <div data-role="page" TodoController-Scope ng:controller="TodoController"> inputText: 'new todo' erzeugt <input type="text" todos: [...] name="inputText" bindet bindet <div ng:repeat="todo in todos"> erzeugt Repeater Scope Repeater Scope Repeater Scope todo: { todo: todo: { { <input type="checkbox" value="todo.done"/> done: false done: false done: false bindet name: 'makemoney' name: 'makemoney' name: 'makemoney' <label> {{todo.name}} } </label> bindet }}
  • 45. jQuery Mobile und AngularJS Das Problem: Die DOM-Manipulationen von jQuery Mobile und AngularJS müssen koordiniert werden!
  • 46. jQuery Mobile und AngularJS Die Lösung: jQuery Mobile Angular Adapter
  • 47. jQuery Mobile Angular Adapter Koordination von jQuery Mobile und AngularJS Erweiterungen für mobile Web-Apps Open Source unter https://github.com/tigbro/ jquery-mobile-angular-adapter
  • 49. Dependency Injection ist ein Entwurfsmuster und dient dazu, die Abhängigkeiten zwischen Komponenten zu minimieren. Es überträgt die Verantwortung für das Erzeugen und die Verknüpfung von Objekten an ein extern konfigurierbares Framework http://de.wikipedia.org/wiki/Dependency_Injection
  • 50. Dependency Injection ist ein Entwurfsmuster und dient dazu, die Abhängigkeiten zwischen Komponenten zu minimieren. Es überträgt die Verantwortung für das Erzeugen und die Verknüpfung von Objekten an ein extern konfigurierbares Framework http://de.wikipedia.org/wiki/Dependency_Injection
  • 51. Beispiel: Backend-Anbindung function refreshTodos() { var self = this; read('ToDoApp', function(response) { self.todos = response; }); }
  • 52. Beispiel: Backend-Anbindung function refreshTodos() { var self = this; read('ToDoApp', function(response) { self.todos = response; }); }
  • 53. Beispiel: Backend-Anbindung var readUrl = 'https://secure.openkeyval.org/'; function read(key, success) { var url = readUrl + key; waitdialog.show(); jsonp(url, function(data) { success(data); waitdialog.hide(); }); }
  • 54. Beispiel: Backend-Anbindung var readUrl = 'https://secure.openkeyval.org/'; function read(key, success) { var url = readUrl + key; waitdialog.show(); jsonp(url, function(data) { success(data); waitdialog.hide(); }); }
  • 55. Beispiel: Backend-Anbindung var readUrl = 'https://secure.openkeyval.org/'; function read(key, success) { var url = readUrl + key; waitdialog.show(); jsonp(url, function(data) { success(data); waitdialog.hide(); }); }
  • 56. Beispiel: Backend-Anbindung waitDialog todoController todoStore key value key value key value ... ... refreshTodos ... read ... todoStore waitDialog jsonp jsonp key value ... ... created by Factories
  • 57. Beispiel: Backend-Anbindung waitDialog todoController todoStore key value key value key value ... ... refreshTodos ... read ... todoStore waitDialog jsonp jsonp key value ... ... created by Dependency Injection
  • 58. Angular JS Declarative MVC with UI Templates Dependency Injection Two-Way Framework Data Binding http://angularjs.org/#/
  • 59. Services und DI mit Angular function jsonpFactory() { // returns jsonp function // ... } function waitdialogFactory() { // returns waitdialog object // ... }
  • 60. Services und DI mit Angular var module = angular.module("todo", []);
  • 61. Services und DI mit Angular var module = angular.module("todo", []); module.factory('jsonp', jsonpFactory); module.factory('waitdialog', waitdialogFactory);
  • 62. Services und DI mit Angular var module = angular.module("todo", []); module.factory('jsonp', jsonpFactory); module.factory('waitdialog', waitdialogFactory); function todoStoreFactory(jsonp, waitdialog) { function read(key, success) { // use jsonp, waitdialog here } return { read: read }; }
  • 63. Services und DI mit Angular var module = angular.module("todo", []); module.factory('jsonp', jsonpFactory); module.factory('waitdialog', waitdialogFactory); function todoStoreFactory(jsonp, waitdialog) { function read(key, success) { // use jsonp, waitdialog here } return { read: read }; } todoStoreFactory.$inject = ['jsonp', 'waitdialog'];
  • 64. Services und DI mit Angular var module = angular.module("todo", []); module.factory('jsonp', jsonpFactory); module.factory('waitdialog', waitdialogFactory); function todoStoreFactory(jsonp, waitdialog) { // ... } todoStoreFactory.$inject = ['jsonp', 'waitdialog']; module.factory('todoStore', todoStoreFactory);
  • 65. Controller und DI mit Angular function TodoController($scope, todoStore) { ... } TodoController.$inject = ['$scope', 'todoStore']; module.controller("rylc.TodoController", TodoController);
  • 66. Controller und DI mit Angular function TodoController($scope, todoStore) { ... } TodoController.$inject = ['$scope', 'todoStore']; module.controller("rylc.TodoController", TodoController);
  • 67. Controller und DI mit Angular function TodoController($scope, todoStore) { ... } TodoController.$inject = ['$scope', 'todoStore']; module.controller("rylc.TodoController", TodoController);
  • 68. jQuery Mobile Angular Adapter Koordination von jQuery Mobile und AngularJS Erweiterungen für mobile Web-Apps Open Source unter https://github.com/tigbro/ jquery-mobile-angular-adapter
  • 69. jQuery Mobile Angular Adapter Mobile Events
  • 70. <div id="main" data-role="page" ng:controller="TodoController" ngm:pagebeforeshow="refreshTodos()"> ... </div> Unterstütze Events: click swipe pagebeforeshow swiperight pageshow swipeleft pagebeforehide tap pagehide taphold
  • 71. jQuery Mobile Angular Adapter Shared Controller
  • 72. LoginPage <div id="loginPage" Scope ng-controller="LoginController"> login <a ngm:click="login()">
  • 73. LoginPage <div id="loginPage" Scope ng-controller="LoginController"> login <a ngm-click="login()"> <div id="welcomePage" WelcomePage ng-controller="WelcomeController"> Scope logout <a ngm-click="logout()">
  • 74. LoginPage <div id="loginPage" Scope ngm-shared-controller= Authentication- "auth:AuthenticationController"> auth Controller Scope <a ngm-click="login()"> login logout <div id="welcomePage" WelcomePage ngm-shared-controller= Scope "auth:AuthenticationController"> auth <a ngm-click="logout()">
  • 75. LoginPage <div id="loginPage" Scope ngm-shared-controller= Authentication- "auth:AuthenticationController"> auth Controller Scope <a ngm-click="auth.login()"> login logout <div id="welcomePage" WelcomePage ngm-shared-controller= Scope "auth:AuthenticationController"> auth <a ngm-click="auth.logout()">
  • 76. jQuery Mobile Angular Adapter Wait Dialog
  • 78. Fazit Auch bei der Entwicklung von JavaScript Clients sollten geeignete Entwurfsmuster angewendet werden!
  • 79. Fazit Bibliotheken und Frameworks helfen bei der Umsetzung!
  • 80. Fazit Eine praxiserprobte Kombination für die Entwicklung mobiler Web-Apps: jQuery Mobile + AngularJS + jQuery Mobile Angular Adapter
  • 81. In the hive 11: nectar and pollen by Max xx, http://www.flickr.com/photos/max_westby/4567762490 Books By Rodrigo Galindez, http://www.flickr.com/photos/rodrigogalindez/4637637337/ IMG_1300-Edit by Susan E Adams, http://www.flickr.com/photos/susanad813/3912914836/ Doble Via by amslerPIX, http://www.flickr.com/photos/amslerpix/6242266697/ MacBook Pro Keyboard by superstrikertwo, http://www.flickr.com/photos/superstrikertwo/4989727256/ Stubborn Last Drop by RogueSun Media, http://www.flickr.com/photos/shuttercat7/627798443/
  • 82. Vielen Dank für Ihr Interesse! @stefanscheidt