a lap around winjs windows store applications for … · 2014-05-22 · a lap around winjs windows...
TRANSCRIPT
http://www.interknowlogy.com/
A LAP AROUND WINJS WINDOWS STORE
APPLICATIONS FOR THE WEB DEVELOPER – PART 2
Philip Japikse (@skimedic)
www.skimedic.com/blog
MVP, MCSD.Net, MCDBA, CSM, CSP
Developer Evangelist, Telerik
PHIL.TOSTRING()
2
• Evangelism Lead - DevTools, Telerik, Inc.
• Microsoft MVP, MCSD, MCDBA, CSM, CSP
• Lead Director, Cincinnati .NET User’s Group
• Co-host Hallway Conversations Podcast
• www.hallwayconversations.com
• Founder, Agile Conferences, Inc.
• www.dayofagile.org
PROCESS LIFECYCLE MANAGEMENT
3
APPLICATION STATES
4
• Activated (onactivated)
•Launched (ActivationKind.launch)
•Search (ActivationKind.search)
•SendTo (ActivationKind.shareTarget)
• Suspended (oncheckpoint)
• ApplicationExecutionState.suspended
• Resumed (onactivated)
• previousExecutionState.suspended
• Terminated
APPLICATION LIFECYCLE
5
ACTIVATION
6
app.onactivated = function (args) { switch (args.detail.kind) {
case activation.ActivationKind.launch: if (args.detail.previousExecutionState !==
activation.ApplicationExecutionState.terminated) { } else { } processPage(args); break;
} };
SEARCH ACTIVATION
7
app.onactivated = function (args) { switch (args.detail.kind) {
case activation.ActivationKind.search: searchTerm = args.detail.queryText; if (args.detail.previousExecutionState !==
activation.ApplicationExecutionState.suspended) {
JSONHandler.getContacts(); processPage(args);
} WinJS.Navigation.navigate("pages/search/search.ht
ml", { searchTerm: searchTerm });
break; }
};
SUSPENSION
8
app.oncheckpoint = function (args) { app.sessionState.history = WinJS.Navigation.history;app.sessionState.location = WinJS.Navigation.location;args.setPromise(JSONHandler.saveContacts());
}; --------------------------------------------------------------------saveContacts: function() {
return new WinJS.Promise(function(fDone, fError, fProgress) { //Save contacts});
}
SESSION STATE
9
app.onactivated = function (args) {//removed for brevityif (app.sessionState.history) {
WinJS.Navigation.history = app.sessionState.history;} if (app.sessionState.location) {
WinJS.Navigation.navigate(app.sessionState.location);}
}
Process Lifecycle Management
10
CONTRACTS
11
SEARCH
12
ADDING SEARCH
13
• Add Search Declaration in package.appmanifest
• Handle Search activation in app.onactivated
• Display Search Results
ADDING SEARCH DECLARATION
14
HANDLING SEARCH ACTIVATION
15
app.onactivated = function (args) { switch (args.detail.kind) {
case activation.ActivationKind.search: searchTerm = args.detail.queryText; if (args.detail.previousExecutionState !==
activation.ApplicationExecutionState.suspended) {// Restore application state
args.setPromise(WinJS.UI.processAll()); } WinJS.Navigation.navigate("pages/search/search.html",
{ searchTerm: searchTerm }); break;
};
PASS SEARCH TERM TO RESULTS PAGE
16
WinJS.UI.Pages.define("pages/search/search.html", { ready: function (element, data) {
ViewModel.searchContacts(data.searchTerm); }
});
searchContacts: function (searchTerm) { SearchResults.contactList = ContactData.contactList.createFiltered(function (c) {
return c.lastName.toLowerCase().indexOf(searchTerm.toLowerCase()) !== -1;
}) }
SHARE SOURCE
17
ADDING SHARE SOURCE
18
• (Optional) Get Deferral
• Add eventlistener to “datarequested” event
• Populate the request object
• Data
•Properties (title, description, applicationName)
•Set value
•setText
•setHTMLFormat
SETTING UP SHARING
19
listView.addEventListener('selectionchanged', function (e) { if (this.winControl.selection.count() != 0) {
listView.selection.getItems().then(function (items) { Contacts.Sharing.itemToShare = currentItem;
}); Contacts.Sharing.startSharing();
} else {
Contacts.Sharing.stopSharing(); }
});
STARTING/STOPPING SHARING
20
var share = Windows.ApplicationModel.DataTransfer; var shareMgr = share.DataTransferManager; WinJS.Namespace.define("Contacts.Sharing", {
itemToShare: null, startSharing: function () {
shareMgr.getForCurrentView().addEventListener("datarequested",
Contacts.Sharing.shareHandler); }, stopSharing: function () {
shareMgr.getForCurrentView().removeEventListener("datarequested",
Contacts.Sharing.shareHandler); },
});
SHARE
21
WinJS.Namespace.define("Contacts.Sharing", { shareHandler: function (e) {
var deferral = e.request.getDeferral(); var request = e.request; var item = Contacts.Sharing.itemToShare; request.data.properties.title = "Contact Information"; request.data.properties.description = "Contact Record for
" + item.lastName; request.data.properties.applicationName = "WinJS
Samples";request.data.setHtmlFormat(
share.HtmlFormatHelper.createHtmlFormat("First Name:" + item.firstName + "<br/>" + "Last Name:" + item.lastName + "<br/>" + "Age:"
+ item.age)); deferral.complete();
}, });
SETTINGS
22
ADDING SETTINGS
23
• Create Settings Flyout
• Add to Settings Charm
• Read/Write Settings Data
• Local Storage
• Roaming Storage
•<Optional> HighPriority
• ApplicationDataCompositeValue
CREATING SETTINGS FLYOUT
24
<div id="colorsDiv" data-win-control="WinJS.UI.SettingsFlyout"data-win-options="{width:narrow}">
<div class="win-header"><button id="backbutton" class="win-backbutton"></button><div class="win-label">Colors</div>
</div><div class="win-content">
<div><h2>Background Color</h2><input id="backgroundColorInput" data-win-bind="value:backgroundColor" />
</div><div>
<h2>Text Color</h2><input id="textColorInput" data-win-bind="value:textColor" />
</div><button id="saveColorsButton">Save</button>
</div></div>
RESPONDING TO REQUEST FOR SETTINGS
25
app.onsettings = function (e) { e.detail.applicationcommands = {
"colorsDiv":{href:"pages/settings/colorsettings.html", title:"Colors"} }; WinJS.UI.SettingsFlyout.populateSettings(e);
};
READ/WRITE SETTINGS
26
(function () { "use strict"; WinJS.UI.Pages.define("/pages/settings/colorsettings.html
", { ready: function(element) {
$('#colorsDiv input').listen('change', function(e) {
ApplicationState.Settings.backgroundColor = backgroundColorInput.value;
ApplicationState.Settings.textColor = textColorInput.value;
}); backbutton.addEventListener('click', function(e)
{ WinJS.UI.SettingsFlyout.show();
}); WinJS.Binding.processAll(colorsDiv,
ApplicationState.Settings); },
}); })();
PERSISTING APPLICATION SETTINGS
27
var storage = Windows.Storage; storage.ApplicationData.current.localSettings.values[setting] = newVal;
//Using Roaming Settingsstorage.ApplicationData.current.roamingSettings.values[setting] = newVal;
//Listening for Changes to Roaming Settingsstorage.ApplicationData.current.addEventListener("datachanged", function(e) {
loadSettings(); });
//Increasing the priority of a setting storage.ApplicationData.current.roamingSettings.values[HighPriority] = newVal;
PERSISTING COMPLEX VALUES
28
var storage = Windows.Storage; var settings =
storage.ApplicationData.current.roamingSettings; WinJS.Namespace.define("ApplicationState", {
compositeContainer: newWindows.Storage.ApplicationDataCompositeValue(),
}); ApplicationState.compositeContainer.insert(setting, newVal);
settings.values["HighPriority"] = ApplicationState.compositeContainer;
XML HTTP REQUESTS AND JSON
29
XML HTTP REQUESTS
30
• WinJS.xhr(options).done(/* success & error handlers */)
• type – GET(default) / HEAD / POST
• url (required)
• user/password
• responseType
• text (default), arrayBuffer, document (xml), json, plus more
• headers
• data (package for send)
JSON
31
• JSON.parse(text [,reviver])
• JSON.stringify(value [, replacer] [,space]
PARSING JSON
32
var items = JSON.parse(contactJSON); items.forEach(function (item) {
ViewModel.addContact( item.firstName, item.lastName, item.age, item.address);
});
---------------------------------------------------------------------------------------------------
var items = JSON.parse(contactJSON, dateReviver); function dateReviver(key, value) {
/* do something meaningful */return updatedValue
});
RENDERING JSON
33
var memberfilter = new Array();memberfilter[0] = "firstName"; memberfilter[1] = "lastName"; memberfilter[2] = "age";var contacts = JSON.stringify(
contactList.slice(0), memberfilter);--------------------------------------------------------------------------------------------------
var contacts = JSON.stringify(contactList.map(convertContacts));convertContacts: function (contact) {
var simpleContact = returnSimpleContactInfo(contact);if (contact.address) {
simpleContact.address = returnSimpleAddressInfo(contact.address);
}return simpleContact;
}
JSON
34
TILES
35
BADGES
36
CREATING A BADGE
37
• Create Badge Type
• Get and Update Badge XML
• Create BadgeNotification
• Update Badge with
TileNotificationManager
CREATING A BADGE
38
createBadge: function (value) { var badgeType = notify.BadgeTemplateType.badgeNumber; var badgeXml =
notify.BadgeUpdateManager.getTemplateContent(badgeType); //"<badge value=\"\"/>" badgeXml.getElementsByTagName("badge")[0].setAttribute("value",
value); var badgeNotification = new notify.BadgeNotification(badgeXml); notify.BadgeUpdateManager.createBadgeUpdaterForApplication().upd
ate(badgeNotification); },-------------------------------------------------------------------------------------------------addContact: function (firstName, lastName, age, address) {
//Omitted for brevity Badges.createBadge(Model.ContactList.length); return newContact;
},
Badges
39
PINNING TILES
40
PINNING A TILE
41
pinTile: function (contact) { var uri = new Windows.Foundation.Uri(
"ms-appx:///images/ConfBuddy_small.png"); var start = Windows.UI.StartScreen; var tile = new start.SecondaryTile(
contact.lastName, // Tile ID contact.lastName + " (" + contact.age + ")", // short
name contact.lastName + ", " + contact.firstName, //display
name JSON.stringify(returnSimpleContactInfo(contact)), //
Activation argument start.TileOptions.showNameOnLogo, // Tile options uri // Tile logo URI
); tile.requestCreateAsync();
},
RESPONDING TO PINNED TILE LAUNCHES
42
app.onactivated = function (args) { switch (args.detail.kind) {
case activation.ActivationKind.launch: if (args.detail.arguments !== "") {
// Reconstitute Contact WinJS.Navigation.navigate("pages/contact/conta
ct.html", { contact: item });
return; }//Omitted for brevity
} }
Pinning Tiles
43
LIVE TILES
44
CREATING A LIVE TILE
45
• Create Square and Wide Tile XML
• Choose Tile Template
• Get and Update Tile XML
• Merge both into 1 XML Doc
• Create TileNotification
• Update Tile with TileNotificationManager
• Can also create Notification Queue
Live Tiles
46
TOAST NOTIFICATIONS
47
CREATING TOAST
48
• Create Toast Template
• Get and Update Toast XML
• Optional:
• Set duration
• Set Audio
• Create ToastNotification with ToastNotificationManager
• Show toast
CREATING TOAST
49
function (title,line1, param) { var template = notify.ToastTemplateType.toastText02; var toastXml =
notify.ToastNotificationManager.getTemplateContent(template); var toastTextElements =
toastXml.getElementsByTagName("text"); toastTextElements[0].appendChild(toastXml.createTextNod
e(title)); toastTextElements[1].appendChild(toastXml.createTextNod
e(line1)); toastXml.selectSingleNode("/toast").setAttribute("launc
h", param); var toast = new notify.ToastNotification(toastXml); var toastNotifier =
notify.ToastNotificationManager.createToastNotifier(); toastNotifier.show(toast);
}
Toast Notifications
50
CONTACT ME
51
•www.skimedic.com/blog
•www.twitter.com/skimedic
•www.hallwayconversations.com
•www.about.me/skimedic
WinJS In Action
52