Windows Store Apps mit HTML & JS entwickeln

Preview:

DESCRIPTION

Windows Store Apps mit HTML & JS entwickeln. Christian Moser Software Architekt und UX Designer, Zühlke moc@zuehlke.com | @ christian_moser | wpftutorial.net. Ziele. Sie wissen wann HTML/JS/CSS die geeignete Entwicklungsplattform für eine App ist . - PowerPoint PPT Presentation

Citation preview

Windows Store Apps mit

HTML & JS entwickelnChristian MoserSoftware Architekt und UX Designer, Zühlke

moc@zuehlke.com | @christian_moser | wpftutorial.net

ZieleSie wissen wann HTML/JS/CSS die geeignete Entwicklungsplattform für eine App ist.Sie kennen die grundlegenden Konzepte einer JavaScript AppSie sind in der Lage selber eine einfache HTML/JS App zu entwickeln.

Agenda

Agenda1. HTML/JS als App-Sprachen2. Aufbau einer HTML/JS App3. Classes and Namespaces4. Application Lifecycle und State handling5. Pages und Navigation6. Controls7. DataBinding8. Model-View-ViewModel Pattern9. Windows Runtime10. Third-Party Libraries

HTML/JS als App-SprachenTeil 1

Motivation für HTML/JS als App-Sprachen? Sie haben bereits Erfahrung mit Web-Technologien Es bestehen bereits JavaScript-Komponenten Sie möchten Cross-Platform entwickeln Sie binden Services ein, die JSON-Daten liefern

(können) Sie sind heimlich verliebt in jQuery, require.js oder

knockout?

Typische “Smells” der Webentwicklung Jeder Browser interpretiert Standards

unterschiedlich HTML5 und CSS3 sind nur auf neusten Browsern

verfügbar JavaScript bietet out-of-the-box keine Konstrukte

für grössere Mengen Code (z.B. Klassen, Namespaces, Interfaces, Module)

JavaScript Performance ist schlecht auf älteren Browsern

Sandboxed (kein Dateizugriff, Office Integration,…)

Apps vs. Web-Pages

Diverse Browser

IE10 (mit all seinen Features)Multi- oder Single-

PageSingle-Page

Sandboxed Plattform-Zugriff (WinRT)jQuery, Knockout,

requireJSWinJS, jQuery, Knockout,

requireJS

AudioExplosion Demo - IE TestdriveAudioExplosionApp

Demo Audio Explosion

Aufbau einer HTML/JS AppTeil 2

WinJS

Unser Werkzeugkoffer

CSS 3 WinRT

HTML 5 JavaScript 5Visual StudioTemplates

Knockout,jQuery,require.js

Visual Studio TemplatesBlank Navigatio

nGridSplit Fixed

Leere App navigator.js,Home-Page

Grid-View, List-View,Sample Data

Grouped ListViewText-Wrapping

Fixed size inViewBox

Demo – Aufbau einer App

Application Lifecycle und StateTeil 3

App LifecycleActivation ReasonsLaunchedSecondary TileSearch targetShare targetProtocol activatedFile Save PickerFile Open PickerFile ActivatedCached File UpdateDevice activatedCamera SettingsPrint task

NotRunning

Running

Suspended

TerminatedSpeichermangel

Resumingin den Vordergrund

Suspending5s im Hintergrund

ActivatedCrashed

Application Objectvar app = WinJS.Application, webApp = Windows.UI.WebUI.WebUIApplication, activation = Windows.ApplicationModel.Activation;

Activatingapp.onactivated = function (e) { if (e.detail.kind === activation.ActivationKind.launch) { // Initialization }};

Suspendingapp.oncheckpoint = function (e) { // Save State and Navigation};

ResumingwebApp.addEventListener("resuming", function (e) { // Restore State and Navigation}, false);

State and History beibehalten

var app = WinJS.Application;var nav = WinJS.Navigation; app.oncheckpoint = function (e) { app.sessionState.history = nav.history; app.sessionState.myData = myData;};

webApp.addEventListener("resuming", function (e) { nav.history = app.sessionState.history; myData = app.sessionState.myData;};

WinJS.Application.sessionState

Objekte im SessioState müssen JSON serialisierbar sein.

Demo - Visual Studio Template

Pages und NavigationTeil 4

Page definition<div id="contenthost">

</div>

var host = document.getElementById('contentHost');WinJS.Pages.render("/pages/home/home.html", host);

WinJS.UI.Pages.define("/pages/home/home.html", { ready: function (element, options) { // Initialize page }});

Page 1

Navigationnavigator.js

WinJS.Pages.render()

WinJS.Navigation.onnavigating

WinJS.Navigation.back(1);

/pages/home/home.html

Page 1

WinJS.Navigation.navigate("/add/add.html");

/pages/add/add.html

Page 2

WinJS.Navigation.forward();

/pages/detail/detail.html

Page 3

ControlsTeil 5

Modern UI Controls

HTML5 Controls mit Win8-Styling

<button class="win-backbutton"></button>

<select> <option>Option 1</option> <option>Option 2</option> <option>Option 3</option></select>

<input type="range" class="win-vertical"/>

<progress class="win-ring win-large" />

WinJS Controls<div data-win-control="WinJS.UI.Rating" data-win-options="{averageRating:3, maxRating:8}"></div>

WinJS.UI.processAll(root);

<div data-win-control="WinJS.UI.AppBar"> <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{label:'Add Album', icon:'add'}" > </button></div>

Styling von Controls

input[type=text]:hover::-ms-clear { background: purple;}

ControlTag

StatePseudo-Class

PartPseudo-Element

Liste aller WinJS-Control-PartsControl Partsinput [type = checkbox] -ms-checkinput [type = radio] -ms-checkinput [type = range] -ms-fill-lower, -ms-track,

-ms-fill-upper, -ms-thumb, -ms-ticks-after, -ms-ticks-before, -ms-ticks-on-track

input [type = email], input [type = search], input [type = tel], input [type = url]

-ms-value, -ms-clear

input [type = password] -ms-value, -ms-revealprogress -ms-fillselect -ms-value, -ms-expand

Classes and Namespaces

Teil 6

Closures(function() { "use strict";

// isolierter Code 

})();

Self-executing anonymous function verhindert Nameskollisionen im globalen Namespace.

Klassen in WinJSvar MyClass = WinJS.Class.define(function() { // Constructor}, { // Members}, { // Static members});

var myObj = new MyClass();

var Person = WinJS.Class.define(function (firstname, lastname) { this._firstname = firstname; this._lastname = lastname; }, {  fullName: { get: function () { return this.firstname + " " + this.lastname; } } }); var hans = new Person("Hans", "Muster");console.log(hans.FullName);

Private Members und Properties

Private Members Wenn Name mit Underscore (“_”) beginnt

Propertiesproperty: { get : function(){}, set : function(value){}}

Namespaces in WinJSWinJS.Namespace.define("Shape", { // Classes MyClass : WinJS.Class.define(function() {}),

  // Functions myFunction : function() {},

    // Values myValue: 5 }); var myInstance = new Shape.MyClass();

Vererbung von Klassenvar Person = WinJS.Class.define(function (firstname, lastname) { this._firstname = firstname; this._lastname = lastname;}, { fullname: { get: function () { return this.firstname + " " + this.lastname; } }});

var Employee = WinJS.Class.derive(Person, function(firstname, lastname, role) { this._firstname = firstname; this._lastname = lastname; this._role = role;}, { description : { get: function () { return this.fullname + " is a " + this._role; } }});

Data BindingTeil 7

Was ist an diesem Code schlecht?var button = document.getElementById('change-button'), person = document.getElementById('person');

button.addEventListener('clicked', function () { person.innerHTML = "Michael Müller";});

Schlecht testbar Abhängigkeit vom Code zur View Kann nicht wiederverwendet werden

<button id="change-button"></button><div id="person">Hans Muster</div>

Besserer Code

var viewModel = WinJS.Class.define(function () {}, { person = { name: "Hans Muster" },  changeName: function () { this.person.name = "Michael Müller"; }});

Gut testbar Keine Abhängigkeit zwischen Model und View Kann wiederverwendet werden

Binding fehlt

<button id="change-button"></button><div id="person">Hans Muster</div>

Data Binding in WinJS

Source TargetBindingConverter

var person = { name: "Hans Muster",};

<div id="root"> <p data-win-bind="textContent:name"></p></div>

var root = document.getElementById("root");WinJS.Binding.processAll(root, person);

DataContext

Bindable Wrappers

var person = { name: "Hans Muster",};

var bindablePerson = WinJS.Binding.as(person);

Erzeugt ein Wrapper mit Properties und Change-Notification.

var bindablePerson = WinJS.Class.define(function() { this._initObservable();}, { name: { get: function () { return getProperty("name"); }, set: function (value) { setProperty("name", value); } }}); WinJS.Class.mix(bindablePerson, WinJS.Binding.mixin);

Binding Mixinvar BindablePerson = WinJS.Class.define(function() { this._initObservable();}, { name : { get: function () { return getProperty("name"); }, set: function (value) { return setProperty("name", value); } }}); WinJS.Class.mix(WinJS.Binding.mixin, BindablePerson);

<div id="root"> <button data-win-bind="onclick:changeName"></button> <p data-win-bind="textContent:person.name"></p></div>

var ViewModel = WinJS.Class.define(function () {

},{ person: WinJS.Binding.as({ name: "Hans Muster" }), changeName: function () { this.person.name = "Michael Müller"; }});

Event Binding

WinJS.Binding.processAll(root, new ViewModel());

Errorperson is undefined.

ErrorValue is not supported within a declarative processing context.

Event Binding<div id="root"> <button data-win-bind="onclick:changeName"></button> <p data-win-bind="textContent:person.name"></p></div>

var ViewModel = WinJS.Class.define(function () { this.changeName = this._changeName.bind(this); this.changeName.supportedForProcessing = true;},{ person: WinJS.Binding.as({ name: "Hans Muster" }), _changeName: function () { this.person.name = "Michael Müller"; }});

WinJS.Binding.processAll(root, new ViewModel());

Löst Problem mit falschem this callback.Markiert die Funktion als “bindable”.

Binding Collections

var viewModel = WinJS.Class.define(function () { var persons = new WinJS.Binding.List();}, { add: function (name) { this.persons.push({ name: name }); }}); WinJS.Binding.processAll(root, viewModel);

<div data-win-control="WinJS.UI.ListView" data-win-bind="winControl.itemDataSource:persons:dataSource"></div>

Die Binding-List ruft beim Hinzufügen für jedes Item WinJs.Binding.as() auf.

Two Way Binding

<input type="text" data-win-bind="value:searchText Binding.Mode.twoway" />searchText: { get: function () { return this._searchText; }, set: function (value) { this._searchText = value;

this.doSearch(); } }

http://mvvmstack.codeplex.com/

Data TemplatesTeil 8

Data Templates

<div id="movie_template" data-win-control="WinJS.Binding.Template"> <div class="movie" data-win-bind="style.backgroundImage:posterUrl"> <div class="item-overlay"> <p data-win-bind="textContent:title"></p> </div> </div></div>

Tipp: Das äusserte <div> ist nicht Teil des Item-Templates.

<div id="moviesList" data-win-control="WinJS.UI.ListView" data-win-bind="winControl.itemDataSource:movies.dataSource;" data-win-options="{itemTemplate:select('#movie_template')}"></div>

Windows RuntimeTeil 9

Windows Runtime (WinRT)

Windows.Storage.KnownFolders.picturesLibrary .getFilesAsync().then(function (files) { files.forEach(function () { // Do something });});

WinRT (COM)

JavaScript Engine

Language Projection

Windows.DataWindows.DevicesWindows.GraphicsWindows.MediaWindows.NetworkingWindows.SecurityWindows.StorageWindows.Web

Zugriff auf Windows 8 Plattform Ressourcen

PromisesWinJS.xhr({ url: "http://www.google.com" }) .then(function (result) { out.innerText = "Success (" + result.responseText.length + " bytes)"; }, function (error) { out.innerHTML = "Failed to download: " + error.statusText; }, function (result) { out.innerText = "Downloading... " + result.readyState; });

Externe LibrariesTeil 10

jQuery

$('#rating').bind('change', function () { $('#message').append($('<p>Rated: ' + this.winControl.userRating + '</p>'));}); $('#appBarCommand').click(function () { $('#message').append($('<p>Clicked!</p>')); $('#rating')[0].winControl.userRating = 5;});

http://code.jquery.com/jquery-2.0.0b2.js

Rated: 3

Fazit

FazitHTML/JS sind bewährte, ausgereifte Technologien mit vielen Features. Damit lassen sich einfach, vollwertige Apps erstellen.

HTML/JS sind ideal, wenn man sich in einem Web-nahem Umfeld bewegt. (Rest-Services, JavaScript Libraries, bestehende Web-Lösungen)

Für komplexe Business-Logik würde ich immer noch C# bevorzugen (Typsicherheit, Refacoring, Namespaces/Classes/Interfaces Teil der Sprache)

WinJS ist stark bei Modern-UI-Controls, kommt aber in vieler Hinsicht (noch) nicht an Frameworks wie jQuery oder Knockout ran.

Viel Spass beim Ausprobieren und “en Guete”

© 2013 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a

commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Recommended