SlideShare uma empresa Scribd logo
1 de 87
Stefan Scheidt | OPITZ CONSULTING GmbH


JavaScript Data Binding
mit jQuery Mobile
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 3
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
                       Controller   Data     Backend
           UI Values
"AJAX Web App"

Browser                         Server


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

  Browser             Server




  Controller   Data   Backend
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 ist aber:

function TodoController() {
    this.todos = [];
    this.inputText = '';
}

TodoController.prototype.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>)
                               Object
                                             ...



$watch(<expr>, <callback>)
Demo
<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>                                         Das DOM
function TodoController() {
    this.todos = [];
    this.inputText = '';
}

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



                               Der Controller
<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"
             name="todo.done"/>                       done: false
                                                     done: false
                                                    done: false
                                  bindet
                                                      name: 'makemoney'
                                                     name: 'makemoney'
                                                    name: 'makemoney'
      <label>
        {{todo.name}}                           }
      </label>
                              bindet       }}
Damit ist das Ziel fast erreicht, aber...
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

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

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

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

 TodoController.prototype.refreshTodos() {
     var self = this;
     read(readUrl, 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
                         todoStore                 key     value
todoController           key          value        ...     ...
key              value   read         ...
todoStore                waitDialog
                         jsonp                     jsonp
                                                   key     value
                                                   ...     ...

             created                  created by
            with "new"                 Factories
Beispiel: Backend-Anbindung

                                                  waitDialog
                                                  key     value
todoController               todoStore            ...     ...
key              value       key          value
todoStore                    waitDialog
                             jsonp                jsonp
                                                  key     value
                                                  ...     ...
                             created by
                         Dependency Injection
Services und DI mit Angular
angular.service('jsonp', jsonpFactory);
angular.service('waitdialog', waitdialogFactory);
Services und DI mit Angular
angular.service('jsonp', jsonpFactory);
angular.service('waitdialog', waitdialogFactory);

function todoStoreFactory() {
    function read(key, success) { ... }
    // ...
    return {
        read: read
        // ...
    }
}
Services und DI mit Angular
angular.service('jsonp', jsonpFactory);
angular.service('waitdialog', waitdialogFactory);

function todoStoreFactory(jsonp, waitdialog) {
    function read(key, success) { ... }
    // ...
    return {
        read: read,
        // ...
    }
}
todoStoreFactory.$inject = ['jsonp', 'waitdialog'];
Services und DI mit Angular
angular.service('jsonp', jsonpFactory);
angular.service('waitdialog', waitdialogFactory);

function todoStoreFactory(jsonp, waitdialog) {
    function read(key, success) { ... }
    // ...
    return {
        read: read
        // ...
    }
}
todoStoreFactory.$inject = ['jsonp', 'waitdialog'];
angular.service('todoStore', todoStoreFactory);
DI für Controller

// ...
angular.service('todoStore', ...);
DI für Controller

// ...
angular.service('todoStore', ...);

function TodoController(todoStore) {
  // do something with todoStore ...
}
TodoController.$inject = ['todoStore'];
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



         Navigation
<a href="#welcomePage">
<a href=""
   ngm:click="$navigate('welcomePage')">
<a href=""
   ngm:click="$navigate(login(),
                  'success:welcomePage',
                  'failure:loginPage')">
<a href=""
   ngm:click="$navigate(login(),
            'success:slide:welcomePage',
            'failure:loginPage')">
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);
One more thing...
Sencha Touch Angular Adapter
Koordination von Sencha Touch und Angular JS

    Erweiterungen für mobile Web-Apps

        semantisches HTML Markup!

            Open Source unter
        https://github.com/tigbro/
       sencha-touch-angular-adapter
Sencha Touch Angular Adapter
Koordination von Sencha Touch und Angular JS

    Erweiterungen für mobile Web-Apps

        semantisches HTML Markup!

            Open Source unter
        https://github.com/tigbro/
       sencha-touch-angular-adapter
Plain Sencha Touch

<!DOCTYPE html>
<html>
<head>
    <title>TodoMobile</title>
    <link rel="stylesheet" href="lib/sencha-touch.css"/>
    <script src="lib/sencha-touch-1.1.0.js"></script>
    <script src="todo_sencha.js"></script>
</head>
<body>
</body>
</html>
new Ext.Application({launch: function() {
  new Ext.Carousel({
    fullscreen: true,
    items: [{xtype: 'panel',
             scroll: true,
             dockedItems: [{xtype: 'toolbar',
                             dock: 'top',
                             title: 'Todos',
                             items: [{xtype: 'button',
                                      text: 'Save'},
                                     {xtype: 'spacer'},
                                     {xtype: 'button',
                                      text: 'Settings'}]}],
             items: [{xtype: 'textfield',
                       placeHolder: 'enter your todo here',
                       listeners: {action: addTodo}},
                      todoPanel]}
            // Settings panel omitted
  ]});
}});
<st:carousel
   ng:controller="TodoController">
  <st:panel id="todos">
    <st:toolbar dock="top" title="Todos">
      <st:button text="Save"
          st:event="{tap:'saveTodos()'}"/>
    </st:toolbar>
    <st:textfield name="inputText"
        st:event="{action:'addTodo()'}"/>
    <st:checkboxfield
        ng:repeat="todo in todos"
        name="todo.done"
        label="{{todo.name}}"/>
  </st:panel>
</st:carousel>
Fazit


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



Bibliotheken und Frameworks
  helfen bei der Umsetzung!
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

Mais conteúdo relacionado

Mais procurados

2015 Key Ingredient Cook-Off
2015 Key Ingredient Cook-Off2015 Key Ingredient Cook-Off
2015 Key Ingredient Cook-Offirwinvifxcfesre
 
Introducción WebComponents y Visual Studio
Introducción WebComponents y Visual StudioIntroducción WebComponents y Visual Studio
Introducción WebComponents y Visual StudioDavid Chavarri
 
City bars workshop
City bars workshopCity bars workshop
City bars workshopJames Pearce
 
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
 

Mais procurados (6)

2015 Key Ingredient Cook-Off
2015 Key Ingredient Cook-Off2015 Key Ingredient Cook-Off
2015 Key Ingredient Cook-Off
 
Introducción WebComponents y Visual Studio
Introducción WebComponents y Visual StudioIntroducción WebComponents y Visual Studio
Introducción WebComponents y Visual Studio
 
City bars workshop
City bars workshopCity bars workshop
City bars workshop
 
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...
 
Web components v1 intro
Web components v1 introWeb components v1 intro
Web components v1 intro
 
Intro to jQuery UI
Intro to jQuery UIIntro to jQuery UI
Intro to jQuery UI
 

Destaque

Simple Strategies of Email Marketing
Simple Strategies of Email Marketing Simple Strategies of Email Marketing
Simple Strategies of Email Marketing LizBESocial
 
Understand Your Festival
Understand Your FestivalUnderstand Your Festival
Understand Your Festivalfestivalslab
 
iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...
iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...
iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...OPITZ CONSULTING Deutschland
 
Course 2 - 1st session: Failure
Course 2 - 1st session: FailureCourse 2 - 1st session: Failure
Course 2 - 1st session: Failurede-pe
 
Discovering Old & New Customers
Discovering Old & New CustomersDiscovering Old & New Customers
Discovering Old & New Customersfestivalslab
 

Destaque (8)

Simple Strategies of Email Marketing
Simple Strategies of Email Marketing Simple Strategies of Email Marketing
Simple Strategies of Email Marketing
 
Understand Your Festival
Understand Your FestivalUnderstand Your Festival
Understand Your Festival
 
Posters
PostersPosters
Posters
 
iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...
iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...
iOS Einstieg und Ausblick - Mobile DevCon 2011 - OPITZ CONSULTING -Stefan Sch...
 
Course 2 - 1st session: Failure
Course 2 - 1st session: FailureCourse 2 - 1st session: Failure
Course 2 - 1st session: Failure
 
Discovering Old & New Customers
Discovering Old & New CustomersDiscovering Old & New Customers
Discovering Old & New Customers
 
Full Toolset
Full ToolsetFull Toolset
Full Toolset
 
HIV and Ageing in Africa
HIV and Ageing in AfricaHIV and Ageing in Africa
HIV and Ageing in Africa
 

Mais 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
 

Mais 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
 

JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012

  • 1. Stefan Scheidt | OPITZ CONSULTING GmbH JavaScript Data Binding mit jQuery Mobile
  • 3. 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 3
  • 5. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarer mobiler JavaScript Web-Apps
  • 6. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarer mobiler JavaScript Web-Apps
  • 7. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarer mobiler JavaScript Web-Apps
  • 9.
  • 11. "Multi Page Web App" Browser Server HTML-Page Controller Data Backend UI Values
  • 12. "AJAX Web App" Browser Server Change AJAX- Controller Ba Data Engine Events
  • 13. "Single Page Web App" Browser Server Controller Data Backend
  • 17. <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
  • 18. <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
  • 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
  • 23. <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
  • 24. <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
  • 25. Two Way Data Binding
  • 27. $('#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>'; }
  • 28. $('#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>'; }
  • 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. Das Ziel ist aber: function TodoController() { this.todos = []; this.inputText = ''; } TodoController.prototype.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ''; }
  • 36. Angular JS Declarative MVC with UI Templates Dependency Injection Two-Way Framework Data Binding http://angularjs.org/#/
  • 37. Two-Way Databinding read read write Data- write DOM Controller binding watch watch
  • 38. Scopes Scope Expressions $get(<expr>) 'inputText' 'todos.length' $set(<expr>, <value>) Object ... $watch(<expr>, <callback>)
  • 39. Demo
  • 40. <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> Das DOM
  • 41. function TodoController() { this.todos = []; this.inputText = ''; } TodoController.prototype.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ''; } Der Controller
  • 42. <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" name="todo.done"/> done: false done: false done: false bindet name: 'makemoney' name: 'makemoney' name: 'makemoney' <label> {{todo.name}} } </label> bindet }}
  • 43. Damit ist das Ziel fast erreicht, aber...
  • 44. jQuery Mobile und AngularJS Das Problem: Die DOM-Manipulationen von jQuery Mobile und AngularJS müssen koordiniert werden!
  • 45. jQuery Mobile und AngularJS Die Lösung: jQuery Mobile Angular Adapter
  • 46. 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
  • 48. 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
  • 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. Beispiel: Backend-Anbindung var readUrl = 'https://secure.openkeyval.org/'; TodoController.prototype.refreshTodos() { var self = this; read(readUrl, function(response) { self.todos = response; }); }
  • 51. Beispiel: Backend-Anbindung var readUrl = 'https://secure.openkeyval.org/'; TodoController.prototype.refreshTodos() { var self = this; read(readUrl, function(response) { self.todos = response; }); }
  • 52. 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(); }); }
  • 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 waitDialog todoStore key value todoController key value ... ... key value read ... todoStore waitDialog jsonp jsonp key value ... ... created created by with "new" Factories
  • 56. Beispiel: Backend-Anbindung waitDialog key value todoController todoStore ... ... key value key value todoStore waitDialog jsonp jsonp key value ... ... created by Dependency Injection
  • 57. Services und DI mit Angular angular.service('jsonp', jsonpFactory); angular.service('waitdialog', waitdialogFactory);
  • 58. Services und DI mit Angular angular.service('jsonp', jsonpFactory); angular.service('waitdialog', waitdialogFactory); function todoStoreFactory() { function read(key, success) { ... } // ... return { read: read // ... } }
  • 59. Services und DI mit Angular angular.service('jsonp', jsonpFactory); angular.service('waitdialog', waitdialogFactory); function todoStoreFactory(jsonp, waitdialog) { function read(key, success) { ... } // ... return { read: read, // ... } } todoStoreFactory.$inject = ['jsonp', 'waitdialog'];
  • 60. Services und DI mit Angular angular.service('jsonp', jsonpFactory); angular.service('waitdialog', waitdialogFactory); function todoStoreFactory(jsonp, waitdialog) { function read(key, success) { ... } // ... return { read: read // ... } } todoStoreFactory.$inject = ['jsonp', 'waitdialog']; angular.service('todoStore', todoStoreFactory);
  • 61. DI für Controller // ... angular.service('todoStore', ...);
  • 62. DI für Controller // ... angular.service('todoStore', ...); function TodoController(todoStore) { // do something with todoStore ... } TodoController.$inject = ['todoStore'];
  • 63. 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
  • 64. jQuery Mobile Angular Adapter Mobile Events
  • 65. <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
  • 66. jQuery Mobile Angular Adapter Navigation
  • 68. <a href="" ngm:click="$navigate('welcomePage')">
  • 69. <a href="" ngm:click="$navigate(login(), 'success:welcomePage', 'failure:loginPage')">
  • 70. <a href="" ngm:click="$navigate(login(), 'success:slide:welcomePage', 'failure:loginPage')">
  • 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
  • 79. Sencha Touch Angular Adapter Koordination von Sencha Touch und Angular JS Erweiterungen für mobile Web-Apps semantisches HTML Markup! Open Source unter https://github.com/tigbro/ sencha-touch-angular-adapter
  • 80. Sencha Touch Angular Adapter Koordination von Sencha Touch und Angular JS Erweiterungen für mobile Web-Apps semantisches HTML Markup! Open Source unter https://github.com/tigbro/ sencha-touch-angular-adapter
  • 81. Plain Sencha Touch <!DOCTYPE html> <html> <head> <title>TodoMobile</title> <link rel="stylesheet" href="lib/sencha-touch.css"/> <script src="lib/sencha-touch-1.1.0.js"></script> <script src="todo_sencha.js"></script> </head> <body> </body> </html>
  • 82. new Ext.Application({launch: function() { new Ext.Carousel({ fullscreen: true, items: [{xtype: 'panel', scroll: true, dockedItems: [{xtype: 'toolbar', dock: 'top', title: 'Todos', items: [{xtype: 'button', text: 'Save'}, {xtype: 'spacer'}, {xtype: 'button', text: 'Settings'}]}], items: [{xtype: 'textfield', placeHolder: 'enter your todo here', listeners: {action: addTodo}}, todoPanel]} // Settings panel omitted ]}); }});
  • 83. <st:carousel ng:controller="TodoController"> <st:panel id="todos"> <st:toolbar dock="top" title="Todos"> <st:button text="Save" st:event="{tap:'saveTodos()'}"/> </st:toolbar> <st:textfield name="inputText" st:event="{action:'addTodo()'}"/> <st:checkboxfield ng:repeat="todo in todos" name="todo.done" label="{{todo.name}}"/> </st:panel> </st:carousel>
  • 84. Fazit Auch bei der Entwicklung von JavaScript Clients sollten geeignete Entwurfsmuster angewendet werden!
  • 85. Fazit Bibliotheken und Frameworks helfen bei der Umsetzung!
  • 86. 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/
  • 87. Vielen Dank für Ihr Interesse! @stefanscheidt