Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012

3,075 views

Published on

http://www.opitz-consulting.com/go/3-4-11

JavaScript-Clients sind ein wichtiger Bestandteil des Mobile Computings, die wart- und testbare Entwicklung ist aber eine Herausforderung. Data Binding erleichtet das Unterfangen durch die klare Trennung von Anwendungscode und UI.

OPITZ CONSULTING Solution Architect Stefan Scheidt präsentierte diesen Vortrag am 27. März 2012 auf der Mobile Tech Conference MTC Spring 2012 in München.

--
Sie möchten mobile Geschäftslösungen in Ihrem Unternehmen nutzen? Wir beraten Sie gerne. Lesen Sie hier mehr zu unseren Leistungen in diesem Bereich und informieren Sie sich zu unserem Workshop für die professionelle Web-App-Entwicklung mit JavaScript: http://www.opitz-consulting.com/go/3-4-898

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

JavaScript Data Binding mit jQuery Mobile - MobileTech Conference Spring 2012

  1. 1. Stefan Scheidt | OPITZ CONSULTING GmbHJavaScript Data Bindingmit jQuery Mobile
  2. 2. Wer bin ich?stefan.scheidt@opitz-consulting.com (@stefanscheidt)
  3. 3. Mission MärkteWir entwickeln gemeinsam mit allen  BranchenübergreifendBranchen Lösungen, die dazu führen, dass  Über 600 Kundensich diese Organisationen besser entwickeln 29%als ihr Wettbewerb. 29% Handel / Logistik / Dienstleistungen Industrie / Versorger /Unsere Dienstleistung erfolgt Telekommunikationpartnerschaftlich und ist auf eine langjährige 42%Zusammenarbeit angelegt. Öffentliche Auftraggeber / Banken und Versicherungen / Vereine und VerbändeLeistungsangebot 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
  4. 4. Wer sind Sie?
  5. 5. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarermobiler JavaScript Web-Apps
  6. 6. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarermobiler JavaScript Web-Apps
  7. 7. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarermobiler JavaScript Web-Apps
  8. 8. Die Beispiel-App ...http://tigbro.github.com/todo-mobilehttps://github.com/tigbro/todo-mobile
  9. 9. Architektur
  10. 10. "Multi Page Web App"Browser Server HTML-Page Controller Data Backend UI Values
  11. 11. "AJAX Web App"Browser Server ChangeAJAX- Controller Ba DataEngine Events
  12. 12. "Single Page Web App" Browser Server Controller Data Backend
  13. 13. Komponenten-Bibliotheken
  14. 14. jQuery Mobile http://jquerymobile.com/
  15. 15. Die Beispiel-App
  16. 16. <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
  17. 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. 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. 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. 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. 21. DOM-Transformationdurch jQuery-Mobile
  22. 22. <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
  23. 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. 24. Two Way Data Binding
  25. 25. Manuelles Binding
  26. 26. $(#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>;}
  27. 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. 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. 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. 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. 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. 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. 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. 34. Das Ziel ist aber:function TodoController() { this.todos = []; this.inputText = ;}TodoController.prototype.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ;}
  35. 35. Angular JSDeclarative MVC withUI Templates Dependency InjectionTwo-Way FrameworkData Binding http://angularjs.org/#/
  36. 36. Two-Way Databinding read read write Data- writeDOM Controller binding watch watch
  37. 37. Scopes Scope Expressions $get(<expr>) inputText todos.length $set(<expr>, <value>) Object ...$watch(<expr>, <callback>)
  38. 38. Demo
  39. 39. <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
  40. 40. function TodoController() { this.todos = []; this.inputText = ;}TodoController.prototype.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ;} Der Controller
  41. 41. <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 }}
  42. 42. Damit ist das Ziel fast erreicht, aber...
  43. 43. jQuery Mobile und AngularJS Das Problem: Die DOM-Manipulationen von jQuery Mobile und AngularJS müssen koordiniert werden!
  44. 44. jQuery Mobile und AngularJS Die Lösung:jQuery Mobile Angular Adapter
  45. 45. jQuery Mobile Angular AdapterKoordination von jQuery Mobile und AngularJS Erweiterungen für mobile Web-Apps Open Source unter https://github.com/tigbro/ jquery-mobile-angular-adapter
  46. 46. Dependency Injection
  47. 47. Dependency Injection ist ein Entwurfsmuster und dient dazu, die Abhängigkeiten zwischen Komponenten zu minimieren. Es überträgt die Verantwortung für dasErzeugen und die Verknüpfung von Objekten an ein extern konfigurierbares Framework http://de.wikipedia.org/wiki/Dependency_Injection
  48. 48. Dependency Injection ist ein Entwurfsmuster und dient dazu, die Abhängigkeiten zwischen Komponenten zu minimieren. Es überträgt die Verantwortung für dasErzeugen und die Verknüpfung von Objekten an ein extern konfigurierbares Framework http://de.wikipedia.org/wiki/Dependency_Injection
  49. 49. Beispiel: Backend-Anbindung var readUrl = https://secure.openkeyval.org/; TodoController.prototype.refreshTodos() { var self = this; read(readUrl, function(response) { self.todos = response; }); }
  50. 50. Beispiel: Backend-Anbindung var readUrl = https://secure.openkeyval.org/; TodoController.prototype.refreshTodos() { var self = this; read(readUrl, function(response) { self.todos = response; }); }
  51. 51. 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(); }); }
  52. 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. 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. 54. Beispiel: Backend-Anbindung waitDialog todoStore key valuetodoController key value ... ...key value read ...todoStore waitDialog jsonp jsonp key value ... ... created created by with "new" Factories
  55. 55. Beispiel: Backend-Anbindung waitDialog key valuetodoController todoStore ... ...key value key valuetodoStore waitDialog jsonp jsonp key value ... ... created by Dependency Injection
  56. 56. Services und DI mit Angularangular.service(jsonp, jsonpFactory);angular.service(waitdialog, waitdialogFactory);
  57. 57. Services und DI mit Angularangular.service(jsonp, jsonpFactory);angular.service(waitdialog, waitdialogFactory);function todoStoreFactory() { function read(key, success) { ... } // ... return { read: read // ... }}
  58. 58. Services und DI mit Angularangular.service(jsonp, jsonpFactory);angular.service(waitdialog, waitdialogFactory);function todoStoreFactory(jsonp, waitdialog) { function read(key, success) { ... } // ... return { read: read, // ... }}todoStoreFactory.$inject = [jsonp, waitdialog];
  59. 59. Services und DI mit Angularangular.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);
  60. 60. DI für Controller// ...angular.service(todoStore, ...);
  61. 61. DI für Controller// ...angular.service(todoStore, ...);function TodoController(todoStore) { // do something with todoStore ...}TodoController.$inject = [todoStore];
  62. 62. jQuery Mobile Angular AdapterKoordination von jQuery Mobile und AngularJS Erweiterungen für mobile Web-Apps Open Source unter https://github.com/tigbro/ jquery-mobile-angular-adapter
  63. 63. jQuery Mobile Angular Adapter Mobile Events
  64. 64. <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
  65. 65. jQuery Mobile Angular Adapter Navigation
  66. 66. <a href="#welcomePage">
  67. 67. <a href="" ngm:click="$navigate(welcomePage)">
  68. 68. <a href="" ngm:click="$navigate(login(), success:welcomePage, failure:loginPage)">
  69. 69. <a href="" ngm:click="$navigate(login(), success:slide:welcomePage, failure:loginPage)">
  70. 70. jQuery Mobile Angular Adapter Shared Controller
  71. 71. LoginPage<div id="loginPage" Scope ng:controller="LoginController"> login <a ngm:click="login()">
  72. 72. 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()">
  73. 73. 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()">
  74. 74. 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()">
  75. 75. jQuery Mobile Angular Adapter Wait Dialog
  76. 76. waitDialog.show(loading);waitDialog.hide();waitDialog.show(click to abort, onClickCallback);
  77. 77. One more thing...
  78. 78. Sencha Touch Angular AdapterKoordination 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
  79. 79. Sencha Touch Angular AdapterKoordination 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. 80. 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>
  81. 81. 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 ]});}});
  82. 82. <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>
  83. 83. Fazit Auch bei der Entwicklung von JavaScript Clientssollten geeignete Entwurfsmuster angewendet werden!
  84. 84. FazitBibliotheken und Frameworks helfen bei der Umsetzung!
  85. 85. In the hive 11: nectar and pollen by Max xx, http://www.flickr.com/photos/max_westby/4567762490 BooksBy 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 Keyboardby superstrikertwo, http://www.flickr.com/photos/superstrikertwo/4989727256/ Stubborn Last Drop by RogueSun Media, http://www.flickr.com/photos/shuttercat7/627798443/
  86. 86. Vielen Dankfür Ihr Interesse! @stefanscheidt

×