Your SlideShare is downloading. ×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

JavaScript Data Binding mit jQuery Mobile - Mobile Developer Conference 2012 - OPITZ CONSULTING - Stefan Scheidt

3,235

Published on

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 …

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. Stefan Scheidt, Senior Solution Architect bei OPITZ CONSULTING, hielt diesen Vortrag bei der Mobile Developer Conference (MDC) am 14.02.2012 in Hamburg.

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,235
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Stefan ScheidtOPITZ CONSULTING GmbHJavaScript Data Bindingmit jQuery Mobile/mdc_conference | #mdc12 www.mobile-developer-conference.de
  • 2. Wer bin ich?stefan.scheidt@opitz-consulting.com (@stefanscheidt)
  • 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. Wer sind Sie?
  • 5. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarermobiler JavaScript Web-Apps
  • 6. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarermobiler JavaScript Web-Apps
  • 7. In diesem Vortrag geht‘s um ... ... die Entwicklung testbarer und wartbarermobiler JavaScript Web-Apps
  • 8. Unser Beispiel
  • 9. Architektur
  • 10. "Multi Page Web App"Browser Server HTML-Page Controller Data Backend UI Values
  • 11. "AJAX Web App"Browser Server ChangeAJAX- Controller Ba DataEngine Events
  • 12. "Single Page Web App" Browser Server Controller Data Backend
  • 13. Komponenten-Bibliotheken
  • 14. jQuery Mobile http://jquerymobile.com/
  • 15. Unser Beispiel
  • 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. <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. DOM-Transformationdurch jQuery-Mobile
  • 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. <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. Two Way Data Binding
  • 25. Manuelles Binding
  • 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. $(#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. 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. Angular JSDeclarative MVC withUI Templates Dependency InjectionTwo-Way FrameworkData Binding http://angularjs.org/#/
  • 36. Two-Way Databinding read read write Data- writeDOM Controller binding watch watch
  • 37. Scopes Scope Expressions $get(<expr>) inputText todos.length $set(<expr>, <value>) Object ...$watch(<expr>, <callback>)
  • 38. <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
  • 39. function TodoController() { this.todos = []; this.inputText = ;}TodoController.prototype.addTodo = function() { this.todos.push({ name: this.inputText, done: false }); this.inputText = ;} Der Controller
  • 40. <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 }}
  • 41. Damit ist das Ziel fast erreicht, aber...
  • 42. jQuery Mobile und AngularJS Das Problem: Die DOM-Manipulationen von jQuery Mobile und AngularJS müssen koordiniert werden!
  • 43. jQuery Mobile und AngularJS Die Lösung: jquery-mobile-angular-adapter
  • 44. 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
  • 45. Dependency Injection
  • 46. Beispiel: Backend-Anbindung var readUrl = https://secure.openkeyval.org/; TodoController.prototype.refreshTodos() { var self = this; read(readUrl, function(response) { self.todos = response; }); }
  • 47. Beispiel: Backend-Anbindung var readUrl = https://secure.openkeyval.org/; TodoController.prototype.refreshTodos() { var self = this; read(readUrl, function(response) { self.todos = response; }); }
  • 48. 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(); }); }
  • 49. 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(); }); }
  • 50. 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(); }); }
  • 51. Beispiel: Backend-Anbindung waitDialog key valuetodoController todoStore ... ...key value key valuetodoStore waitDialog jsonp jsonp key value ... ... created created by with "new" Factories
  • 52. Beispiel: Backend-Anbindung waitDialog key valuetodoController todoStore ... ...key value key valuetodoStore waitDialog jsonp jsonp key value ... ... created by Dependency Injection
  • 53. Services und DI mit Angularangular.service(jsonp, jsonpFactory);angular.service(waitdialog, waitdialogFactory);
  • 54. Services und DI mit Angularangular.service(jsonp, jsonpFactory);angular.service(waitdialog, waitdialogFactory);function todoStoreFactory() { function read(key, success) { ... } // ... return { read: read // ... }}
  • 55. 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];
  • 56. 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);
  • 57. DI für Controller// ...angular.service(todoStore, ...);
  • 58. DI für Controller// ...angular.service(todoStore, ...);function TodoController(todoStore) { ...}TodoController.$inject = [todoStore];
  • 59. 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
  • 60. jQuery Mobile Angular Adapter Mobile Events
  • 61. <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
  • 62. jQuery Mobile Angular Adapter Navigation
  • 63. <a href="#welcomePage">
  • 64. <a href="" ngm:click="$navigate(welcomePage)">
  • 65. <a href="" ngm:click="$navigate(login(), success:welcomePage, failure:loginPage)">
  • 66. <a href="" ngm:click="$navigate(login(), success:slide:welcomePage, failure:loginPage)">
  • 67. jQuery Mobile Angular Adapter Shared Controller
  • 68. LoginPage<div id="loginPage" Scope ng:controller="LoginController"> login <a ngm:click="login()">
  • 69. 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()">
  • 70. 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()">
  • 71. 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()">
  • 72. jQuery Mobile Angular Adapter Wait Dialog
  • 73. waitDialog.show(loading);waitDialog.hide();waitDialog.show(click to abort, onClickCallback);
  • 74. One more thing...
  • 75. 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
  • 76. 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>
  • 77. 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 ]});}});
  • 78. <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>
  • 79. Fazit Auch bei der Entwicklung von JavaScript Clientssollten geeignete Entwurfsmuster angewendet werden!
  • 80. FazitBibliotheken und Frameworks helfen bei der Umsetzung!
  • 81. 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/ Stubborn Last Drop by RogueSun Media, http://www.flickr.com/photos/shuttercat7/627798443/
  • 82. Vielen Dankfür Ihr Interesse! @stefanscheidt

×