ในตอนที่ผ่านมา เราได้เพิ่มฟีเจอร์หลักคือการอ่านและเขียนไฟล์ รวมถึงพัฒนาแอพลิเคชันให้เข้ากับลักษณะ Lifecycle แบบใหม่แล้ว ในตอนนี้เราจะเพิ่มความสามารถอื่นๆ สำหรับแอพลิเคชันบน Windows 8 เพิ่มเติม คือ การรองรับการแชร์ และการสร้างเมนูปรับตั้งค่า
โดยปกติหากเราต้องการนำข้อมูลจากโปรแกรมหนึ่งไปใช้ในอีกโปรแกรมหนึ่ง เรามักใช้วิธีลากไปปล่อย อย่างไรก็ตามวิธีนี้ไม่เหมาะกับการใช้งานบนอุปกรณ์พกพานัก บนแอพลิเคชันสำหรับ Windows 8 App Store จะให้ผู้ใช้ส่งข้อมูลระหว่างแอพลิเคชันด้วยวิธีการ "แชร์" ได้ โดยการเรียกเมนูแชร์จาก Charm Bar
การแชร์ข้อมูลให้แอพลิเคชันอื่นนั้น ให้เรารอฟังอีเวนต์ datarequested จาก Windows.ApplicationModel.DataTransfer.DataTransferManager ซึ่งจะถูกส่งออกมาเมื่อผู้ใช้คลิกปุ่ม Share บน Charm Bar เพื่อให้แอพลิเคชันของเราตัดสินใจว่า ขณะนั้นแอพลิเคชันของเรามีข้อมูลอะไรจะให้แชร์หรือไม่ (และข้อมูลนั้นคืออะไร)
เราจะแก้แอพลิเคชันตัวอย่างให้แชร์เนื้อหาทั้งหมดในขณะนั้น หรือเนื้อหาส่วนที่ถูกเลือกถ้าผู้ใช้เลือก (ทำ selection) ไว้ เริ่มต้นจากเพิ่มฟังก์ชัน onDataRequested ในไฟล์ /pages/editor/editor.js ดังนี้
{syntaxhighlighter brush: jscript}var onClickShareButton = function (e) {
var data, title;
if (contentArea.selectionStart != contentArea.selectionEnd) {
// Some text is selected. Share only the selected text.
var startIndex = Math.min(contentArea.selectionStart, contentArea.selectionEnd);
var endIndex = Math.max(contentArea.selectionStart, contentArea.selectionEnd);
title = "Content from selected text";
data = contentArea.innerText.substring(startIndex, endIndex);
}
else {
// No text is selected. Share all text.
title = "Content from current document";
data = contentArea.innerText;
}
var request = e.request;
request.data.properties.title = title;
request.data.properties.description = data;
request.data.setText(data);
};{/syntaxhighlighter}
จากนั้นเพิ่มโค้ดส่วนท้ายของฟังก์ชัน ready ของหน้า editor (ไฟล์ /pages/editor/editor.js) ให้รอฟังอีเวนต์ datarequested ดังนี้ หากมีอีเวนต์เกิดขึ้นให้เรียกฟังก์ชัน onDataRequested ที่สร้างเอาไว้ก่อนหน้านี้ ดังนี้
{syntaxhighlighter brush: jscript}WinJS.UI.Pages.define("/pages/editor/editor.html", {
ready: function (element, options) {
// ...
// Code from previous chapters
// ...
var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
dataTransferManager.addEventListener("datarequested", onDataRequested);
}
});{/syntaxhighlighter}
จากนั้นลองรันแอพลิเคชันและทดลองแชร์
หมายเหตุ: ดูเอกสารคลาส DataPackage เพื่อดูฟังก์ชันที่ใช้แชร์ข้อมูลประเภทอื่นๆ เช่น RTF, HTML, URI, Bitmap, StorageItems
เนื่องจากการเปิดรับข้อมูลที่แชร์ต้องเกิดขึ้นได้แม้ผู้ใช้จะยังไม่ได้เปิดแอพลิเคชันของเรา ดังนั้นส่วนนี้จะเริ่มต้นโดยการสร้าง Share Target Contract ขึ้น เพื่อให้ระบบสามารถรู้ได้ว่าแอพลิเคชันของเรารับข้อมูลอะไรได้บ้าง การสร้าง Contract นี้ยังใช้กับฟีเจอร์อื่นๆ ที่ทำงานในลักษณะเดียวกันนี้ด้วย เช่น Search Contract, File Open Picker Contract เป็นต้น
เราจะเริ่มต้นโดยการสร้างโฟลเดอร์ /pages/shareTarget จากนั้นคลิกขวาที่โฟลเดอร์แล้วเลือกเมนู Add New Item... แล้วเลือกสร้าง Share Target Contract ชื่อ shareTarget.html
จากนั้นเปิดไฟล์ package.appmanifest แล้วไปที่แท็บ Declarations จะพบว่ามี Share Target ระบุไว้ ในหน้านี้เราสามารถระบุได้ว่าจะรับข้อมูลประเภทใดบ้างที่ฟิลด์ Data Format (ซึ่งเราจะแก้ไขให้รับเพียง Text เท่านั้น) และระบุได้ว่าจะให้หน้าใดเป็นหน้ารับข้อมูลที่แชร์มาในส่วน App Settings (ซึ่งหากเราสร้างหน้า Share Contract ด้วยวิธีข้างต้น โปรแกรมจะกำหนดให้เปิดหน้า Share Contract ที่เราสร้างไว้อยู่แล้ว)
หากเราลองเปิดแอพลิเคชันที่แชร์ข้อมูลประเภท Text ได้ (เช่น Internet Explorer ในสถานะที่เลือกข้อความอยู่) จะปรากฎชื่อแอพลิเคชันของเราให้เลือก ซึ่งเมื่อกดเข้าไปจะพบหน้าแชร์ตั้งต้น
เราจะแก้ไขหน้าแชร์ตั้งต้นให้แสดงกล่องข้อความเช่นเดียวกับหน้า editor ดังนี้
HTML (/pages/shareTarget/shareTarget.html)
{syntaxhighlighter brush: xml}
Share Target
{/syntaxhighlighter}
CSS (/pages/shareTarget/shareTarget.css)
{syntaxhighlighter brush: css}section[role=main] {
display: -ms-grid;
width: 100%;
height: 100%;
-ms-grid-columns: 40px 1fr 40px;
-ms-grid-rows: 40px 1fr 20px auto 40px;
}
#contentArea {
box-sizing: border-box;
-ms-grid-column: 2;
-ms-grid-row: 2;
margin: 0;
font-size: x-large;
}
.sharecontrols {
-ms-grid-column: 2;
-ms-grid-row: 4;
-ms-grid-column-align: end;
}{/syntaxhighlighter}
จากนั้นเราจะเขียนโค้ดจาวาสคริปท์ /pages/shareTarget/shareTarget.js เพื่อรับข้อมูลที่ถูกแชร์มา เนื่องจากส่วนรับข้อมูลที่แชร์จากแอพลิเคชันอื่นนี้จะเป็นโปรแกรมที่แยกจากโปรแกรมหลัก ดังนั้นโค้ดในส่วนนี้จึงเขียนเหมือนเป็นอีกแอพลิเคชันหนึ่ง ดังนี้
{syntaxhighlighter brush: jscript}(function () {
"use strict";
var shareOperation;
var contentArea;
WinJS.Application.onactivated = function (args) {
if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
contentArea = document.querySelector("#contentArea");
shareOperation = args.detail.shareOperation;
shareOperation.data.getTextAsync().done(function (text) {
contentArea.innerText = text;
});
}
};
WinJS.Application.start();
})();{/syntaxhighlighter}
เมื่อผู้ใช้เลือกแชร์ข้อมูลมายังแอพลิเคชันของเรา แอพลิเคชันจะถูกเรียกขึ้นมาใหม่ (คนละตัวกับโปรแกรมปกติ หากแอพลิเคชันของเราถูกเปิดอยู่แล้ว) โดยจะระบุสาเหตุที่ถูกเรียกเป็น shareTarget เราสามารถนำข้อมูลที่เกี่ยวข้องกับการแชร์ออกมาได้จากวัตถุ args.detail.shareOperation ซึ่งสามารถดูวิธีการใช้งานอย่างละเอียดได้จากหน้าคลาส ShareOperation
เมื่อทดสอบแอพลิเคชันจะพบข้อความที่ถูกแชร์แสดงใน textarea แล้ว
จากนั้นเราจะกำหนดให้เมื่อผู้ใช้กดปุ่ม Share ให้บันทึกเนื้อหาลงใน Local Storage ไว้ก่อน เพื่อให้ผู้ใช้ไปเปิดได้จากแอพลิเคชันของเราในภายหลัง (เนื่องจากเราไม่สามารถเรียก File Picker จากหน้านี้ได้) โดยเพิ่มเติมโค้ด ดังนี้
{syntaxhighlighter brush: jscript}(function () {
"use strict";
var shareOperation;
var contentArea;
var shareButton;
var onClickShareButton = function() {
var localFolder = Windows.Storage.ApplicationData.current.localFolder;
var generateUniqueName = Windows.Storage.CreationCollisionOption.generateUniqueName;
localFolder.createFileAsync("Shared.txt", generateUniqueName)
.then(function (file) {
return Windows.Storage.FileIO.writeTextAsync(file, contentArea.innerText);
})
.done(function () {
shareOperation.reportCompleted();
});
};
WinJS.Application.onactivated = function (args) {
if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
contentArea = document.querySelector("#contentArea");
shareButton = document.querySelector("#shareButton");
shareButton.addEventListener("click", onClickShareButton);
shareOperation = args.detail.shareOperation;
shareOperation.data.getTextAsync().done(function (text) {
contentArea.innerText = text;
});
}
};
WinJS.Application.start();
})();{/syntaxhighlighter}
โค้ดที่เพิ่มเติมขึ้นจะสร้างไฟล์ใน Local Storage ซึ่งโดยปกติจะเก็บไว้ที่ C:\Users[UserName]\AppData\Local\Packages[ApplicationID]\LocalState ซึ่งแอพลิเคชันสามารถอ่านและเขียนไฟล์ที่นี่ได้โดยไม่ต้องขอสิทธิ์อนุญาตเพิ่มเติม โดยนำวัตถุ Windows.Storage.ApplicationData.current.localFolder เรียกเมธอด createFileAsync เพื่อขอสร้างไฟล์ตามชื่อที่ต้องการ (ในที่นี้กำหนดตัวเลือกพิเศษ generateUniqueName เพื่อให้ระบบเปลี่ยนชื่อให้ถ้าชื่อซ้ำ) จากนั้นจึงเขียนเนื้อหาลงในไฟล์ที่สร้าง
เมื่อแชร์เสร็จเรียบร้อยแล้ว เราจะต้องเรียกเมธอด shareOperation.reportCompleted() เพื่อปิดหน้าต่างนี้เอง อย่างไรก็ตาม ผู้ใช้จะไม่สามารถเลือกไฟล์ที่เราบันทึกไว้ใน Local Storage ได้ ดังนั้นเราจะเพิ่มเติมหน้าแรกให้แสดงไฟล์เหล่านี้ต่อไป
เราจะสร้างลิสต์แสดงไฟล์ใน Local Storage เพิ่มในหน้าแรกของแอพลิเคชัน เพื่อให้ผู้ใช้เปิดไฟล์ในนั้นมาแก้ไขได้ เริ่มต้นโดยแก้ไขไฟล์ /pages/home/home.js เพื่อให้ปล่อย DataSource ของรายการไฟล์ใน Local Storage ของเราออกมา ดังนี้
{syntaxhighlighter brush: jscript}(function () {
"use strict";
// ...
// Code from previous chapters
// ...
var localFolder = Windows.Storage.ApplicationData.current.localFolder;
var orderByName = Windows.Storage.Search.CommonFileQuery.orderByName;
var queryOption = new Windows.Storage.Search.QueryOptions(orderByName, [".txt"]);
WinJS.Namespace.define("StrifePad", {
files: new WinJS.UI.StorageDataSource(localFolder.createFileQueryWithOptions(queryOption))
});
})();{/syntaxhighlighter}
ในที่นี้ DataSource ประเภท WinJS.UI.StorageDataSource โดยให้เราส่งคิวรีเพื่อหาไฟล์และเรียงลำดับตามคุณสมบัติที่เราต้องการ ซึ่งคิวรีนี้เราสร้างได้โดยเรียกเมธอด createFileQueryWithOptions บนโฟลเดอร์ที่เราต้องการหาไฟล์ในนั้น สามารถส่งพารามิเตอร์เป็นการเรียงลำดับ และนามสกุลที่ต้องการได้ จากนั้นแก้ไขไฟล์ /pages/home/home.html เพื่อเพิ่ม ListView ลงไป ดังนี้ (โค้ดนี้ละส่วน head ที่ไม่ได้มีการแก้ไขใดๆ)
{syntaxhighlighter brush: xml}
...
New
Open
{/syntaxhighlighter}
ส่วนที่เพิ่มขึ้นมาเริ่มจากด้านล่าง เราเพิ่ม header สำหรับลิสต์ และคอมโพเนนต์ ListView โดยกำหนดให้ใช้แหล่งข้อมูลจากตัวแปรโกลบอล StrifePad.localStorageFiles (ซึ่งเราได้เตรียมไว้แล้วก่อนหน้านี้) และกำหนดให้แต่ละชิ้นในลิสต์ใช้เทมเพลตจากอิลิเมนต์ไอดี fileItemTemplate
ส่วนอิลิเมนต์ไอดี fileItemTemplate เป็นคอนโทรลประเภท WinJS.Binding.Template ซึ่งต้องประกาศเอาไว้ก่อน ListView ที่เรียกใช้ โดยเราสามารถกำหนดเนื้อในได้ตามต้องการ เพื่อให้แต่ละชิ้นในลิสต์แสดงผลตามต้องการได้ หากเราต้องการนำข้อมูลของแต่ละวัตถุใน DataSource มาแสดงก็ทำได้โดยใช้ binding จากตัวอย่างเราต้องการนำชื่อไฟล์มาแสดงใน span ซึ่งโดยซอร์สโค้ดภาษาจาวาสคริปต์ปกติเราจะเขียนว่า
{syntaxhighlighter brush: jscript}var span;
var file;
span.innerText = file.displayName;{/syntaxhighlighter}
เราสามารถเขียนใหม่แบบ Binding ใน HTML Template ได้ดังนี้
{syntaxhighlighter brush: xml}{/syntaxhighlighter}
กรณีที่ต้องการ bind หลายๆ อย่างในคอมโพเนนต์เดียวกัน สามารถใช้ semi-colon คั่นระหว่างแต่ละคำสั่งใน win-data-bind ได้ แต่ในกรณีนี้ไม่ใช่การใช้ binding ตามปกติ เพราะวัตถุใน DataSource คือไฟล์ ดังนั้นเราจำเป็นต้องกำหนดออพชันพิเศษ WinJS.Binding.oneTime ด้วย (สำหรับผู้ที่เข้าใจเรื่อง Binding บ้างแล้ว ดูรายละเอียดเพิ่มเติมได้จากคำถามคำตอบบน msdn)
จากนั้นตกแต่งเพิ่มเติมด้วย CSS โดยแก้ไขไฟล์ /pages/home/home.css โดยกำหนดขนาดของกริดใหม่ ให้มีสามคอลัมน์ โดยคอลัมน์แรกเป็นปุ่มสองปุ่มเดิม ส่วนคอลัมน์ที่สามเป็นตัวลิสต์ ซึ่งปรับขนาดตามเนื้อหาของลิสต์ (กำหนดขนาดเป็น auto) ดังนี้
{syntaxhighlighter brush: css}.homepage section[role=main] {
box-sizing: border-box;
padding: 20px 120px;
height: 100%;
display: -ms-grid;
-ms-grid-columns: 250px 40px auto;
-ms-grid-rows: auto 20px 120px 10px 120px 1fr;
overflow-x: scroll;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
#tileButtonGroup {
height: calc(100% - 120px);
}
.tileButton {
background: rgb(71, 169, 80);
border: 1px solid rgb(109, 179, 81);
-ms-transition: -ms-transform ease-out 0.2s;
-ms-transform: scale(1.0, 1.0);
}
.tileButton:active {
-ms-transform: scale(0.978395);
}
.tileButton p {
margin: 5px 12px;
font-weight: 200;
font-size: x-large;
}
#newButton {
-ms-grid-row: 3;
-ms-grid-column: 1;
}
#openButton {
-ms-grid-row: 5;
-ms-grid-column: 1;
}
#localStorageHeader {
-ms-grid-row: 1;
-ms-grid-column: 3;
}
.win-listview {
-ms-grid-row: 3;
-ms-grid-row-span: 4;
-ms-grid-column: 3;
}
#mostRecentFilesListView {
margin: 0;
}
#mostRecentFilesListView .win-listview {
width: 100%;
height: 100%;
margin: 0;
}
#mostRecentFilesListView .win-surface {
margin-right: 40px;
}
#mostRecentFilesListView .win-item {
width: 300px;
height: 70px;
padding: 5px 12px;
overflow: hidden;
background-color: #2b496f;
border: solid 1px #385d8c;
}
#mostRecentFilesListView .win-container:not(.footprint):not(.hover) {
background-color: transparent;
}{/syntaxhighlighter}
หมายเหตุ: เราสามารถดูรายการ class ของ CSS ที่เราสามารถกำหนดรูปแบบได้จากเอกสารคอนโทรล ListView หัวข้อ Remarks/Styling the listview และสามารถดูวิธีการตกแต่งคอนโทรลประเภทอื่นๆ ได้ด้วยวิธีทำนองเดียวกันนี้
การสร้างเมนูปรับตั้งค่าก็จะใช้วิธีใกล้เคียงกันกับการแชร์ข้อมูลให้แอพลิเคชันอื่น คือให้เรารอฟังอีเวนต์ settings จาก WinJS.Application ซึ่งจะถูกส่งออกมาเมื่อผู้ใช้คลิกปุ่ม Settings บน Charm Bar เพื่อให้แอพลิเคชันของเราสร้างกำหนดว่าจะมีหน้า Settings ย่อยๆ (เรียกว่า Settings Flyout) อะไรบ้าง เพื่อนำไปแสดงรวมกับเมนูตั้งต้น และเมนูปรับตั้งค่าของเครื่องใน Charm Bar อีกทีหนึ่ง
เริ่มต้นจากเพิ่มโค้ดในไฟล์ /js/default.js เพื่อรอฟังอีเวนต์ settings จาก WinJS.Application และเติมเมนู Options เพิ่มเข้าไป ดังนี้
{syntaxhighlighter brush: jscript}(function () {
"use strict";
// ...
// Code from previous chapters.
//
app.onsettings = function (e) {
e.detail.applicationcommands = {
"options": {
title: "Options",
href: "/pages/options/options.html"
}
};
WinJS.UI.SettingsFlyout.populateSettings(e);
};
app.start();
})();{/syntaxhighlighter}
การเพิ่มเมนูปรับตั้งค่านั้น ให้เราเพิ่มเมนูเข้าไปที่ property detail.applicationcommands ของอีเวนต์ที่ได้รับมา โดยกำหนดเป็นวัตถุที่มีชื่อ property เป็น Command ID ของหน้า และค่าเป็นวัตถุระบุชื่อ และที่อยู่ของหน้านั้นๆ ในตัวอย่าง เรากำหนดให้มีเมนูปรับตั้งค่าเมนูเดียว ซึ่งมี Command ID เป็น options มีชื่อว่า Options ซึ่งเมื่อถูกคลิกจะเรียกหน้า /pages/options/options.html ขึ้นมา
เมื่อเสร็จแล้วจึงเรียกฟังก์ชัน WinJS.UI.SettingsFlyout.populateSettings() เพื่อเรียกแถบ Settings ของ Charm Bar ออกมา หากทดสอบตรงนี้ จะมีเมนู Options เพิ่มขึ้นมาแล้ว จากนั้นเราจะเข้าไปแก้ไขหน้า Options โดยเปิดไฟล์ /pages/options/options.html แล้วสร้างเนื้อหาดังนี้
{syntaxhighlighter brush: xml}
Options
{/syntaxhighlighter}
ในหน้านี้เราจะใช้คอมโพเนนท์ SettingsFlyOut โดยจะต้องกำหนด settingsCommandId ให้ตรงกับที่เราตั้งไว้ก่อนหน้านี้ จากนั้นก็สามารถใส่คอมโพเนนท์ต่างๆ ลงไปใน Settings Flyout ได้
สิ่งที่ควรทราบหลักๆ เกี่ยวกับการสร้างเมนูปรับตั้งค่ามีดังนี้
ในที่นี้เราให้ผู้ใช้ปรับตั้งค่าได้อย่างเดียว คือ เปิดหรือปิดฟังก์ชันการตรวจสอบตัวสะกด โดยใช้คอมโพเนนท์ ToggleSwitch สำหรับปรับตั้งค่านี้
เมื่อทดสอบดูจะพบหน้าปรับตั้งค่าที่เราสร้างขึ้นแล้ว
สุดท้ายเราจะต้องจดจำและโหลดค่าที่ผู้ใช้ปรับไว้ รวมถึงนำค่าที่ผู้ใช้ปรับนี้ไปใช้งานต่อไป โดยการเขียนโค้ดภาษาจาวาสคริปต์เพิ่มเติม
เริ่มต้นจากเปิดไฟล์ /pages/options/options.js
{syntaxhighlighter brush: jscript}(function () {
"use strict";
var checkSpellingToggleSwitch;
var onCheckSpellingToggleSwitchChange = function (event) {
var appData = Windows.Storage.ApplicationData.current;
appData.localSettings.values["checkSpelling"] = checkSpellingToggleSwitch.winControl.checked;
};
WinJS.UI.Pages.define("/pages/options/options.html", {
ready: function (element, options) {
checkSpellingToggleSwitch = element.querySelector("#checkSpellingToggleSwitch");
checkSpellingToggleSwitch.addEventListener("change", onCheckSpellingToggleSwitchChange);
var appData = Windows.Storage.ApplicationData.current;
checkSpellingToggleSwitch.winControl.checked = appData.localSettings.values["checkSpelling"];
}
});
})();{/syntaxhighlighter}
การเขียนหน้า Settings Flyout โดยรวมก็ไม่ต่างจากการเขียนหน้า Page Control ปกติที่เราเขียนกันมาแล้ว โดยโค้ดในส่วนนี้จะเก็บค่าไว้ใน Local Settings (Windows.Storage.ApplicationData.current.localSettings) ซึ่งสามารถเก็บค่าแบบ Key/Value และเรียกกลับมาใช้ได้อย่างง่ายๆ เหมือนการอ่านและเขียน property จากวัตถุตามปกติ
กรณีที่ต้องการให้ Settings นั้นถูกอัพโหลดเก็บไว้เพื่อให้นำค่ากลับมาใช้เมื่อผู้ใช้คนเดียวกันติดตั้งแอพลิเคชันนี้ที่เครื่องอื่น สามารถย้ายไปเก็บที่ Roaming Settings ได้ โดยใช้วิธีเดียวกันนี้
ดูรายละเอียดเพิ่มเติมเกี่ยวกับการเก็บข้อมูลของแอพลิเคชันได้จากเอกสาร
เมื่อทดสอบตรงนี้เมนูของเราก็จะจำค่าที่ผู้ใช้เลือกไว้แล้ว คราวนี้เราจะนำค่าที่ผู้ใช้เลือกนี้ไปใช้ในแอพลิเคชันกัน เริ่มต้นจากแก้ไขไฟล์ /pages/editor/editor.js ในส่วนเริ่มต้นหน้า เพื่อนำค่านี้ไปกำหนดให้กับตัว textarea ดังนี้
{syntaxhighlighter brush: jscript}WinJS.UI.Pages.define("/pages/editor/editor.html", {
ready: function (element, options) {
pageTitle = element.querySelector("#pageTitle");
contentArea = element.querySelector("#contentArea");
bottomAppBar = element.querySelector("#bottomAppBar");
saveButton = element.querySelector("#saveButton");
var appData = Windows.Storage.ApplicationData.current;
contentArea.spellcheck = appData.localSettings.values["checkSpelling"] || false;
// ...
// Code from previous chapters
// ...
}
});{/syntaxhighlighter}
อย่างไรก็ตาม หน้าปรับตั้งค่านี้ยังไม่สมบูรณ์ เนื่องจากค่าที่ผู้ใช้เลือกยังไม่ถูกนำไปใช้โดยทันที ดังนั้นเราจะต้องปรับปรุงโค้ดของเราอีกเล็กน้อย ในที่นี้เราจะทำอย่างง่าย โดยให้หน้า Options ส่งอีเวนต์ checkSpelling (ซึ่งเรากำหนดเอง) ผ่าน WinJS.Application หากมีการเปลี่ยนแปลงค่านี้ เราจะต้องเพิ่มโค้ดใน /pages/options/options.js ดังนี้ (ส่วนที่เป็นตัวหนาแสดงส่วนที่เพิ่มขึ้นมาจากหัวข้อที่แล้ว)
{syntaxhighlighter brush: jscript}(function () {
"use strict";
var checkSpellingToggleSwitch;
var onCheckSpellingToggleSwitchChange = function (event) {
var appData = Windows.Storage.ApplicationData.current;
appData.localSettings.values["checkSpelling"] = checkSpellingToggleSwitch.winControl.checked;
WinJS.Application.queueEvent({
type: "checkSpellingChange"
});
};
WinJS.UI.Pages.define("/pages/options/options.html", {
ready: function (element, options) {
checkSpellingToggleSwitch = element.querySelector("#checkSpellingToggleSwitch");
checkSpellingToggleSwitch.addEventListener("change", onCheckSpellingToggleSwitchChange);
var appData = Windows.Storage.ApplicationData.current;
checkSpellingToggleSwitch.winControl.checked = appData.localSettings.values["checkSpelling"];
}
});
})();{/syntaxhighlighter}
จากนั้นกลับมาแก้ไขไฟล์ /pages/editor/editor.js เพื่อรอฟังอีเวนต์ดังกล่าวและอัพเดท textarea ดังนี้
{syntaxhighlighter brush: jscript}var onCheckSpellingChange = function (e) {
var appData = Windows.Storage.ApplicationData.current;
contentArea.spellcheck = appData.localSettings.values["checkSpelling"] || false;
};
WinJS.UI.Pages.define("/pages/editor/editor.html", {
ready: function (element, options) {
// ...
// Code from previous chapters
// ...
WinJS.Application.addEventListener("checkSpellingChange", onCheckSpellingChange);
// ...
// Code from previous chapters
// ...
}
});{/syntaxhighlighter}
หมายเหตุ: ไม่ควรบันทึก password หรือข้อมูลที่อาจกระทบต่อความปลอดภัยของบัญชีผู้ใช้ไว้ใน local storage โดยแนะนำให้ใช้ PasswordVault แทน
บทความชุด การเขียนแอพลิเคชันสำหรับ Windows 8 App Store
Comments
ตรงส่งเมลแรก ปิดบังเมลคุณแชมป์หน่อยดีมั้ยครับ (O_o)
ขอบคุณครับ โดนเซนเซอร์ไปแล้วครับ
มีคนสั่งมาหรือทางผู้จัดทำเซนเซอร์เองครับ
ทางเราเซนเซอร์เองเนื่องจากมีเนื้อหาบางส่วนไม่เหมาะสมครับ ;p
ทำ ui design บน ios มาดูบน win8 แล้วมันจะ clean เกินไปปะเนีย
ท่านใดพอจะแนะนำ Apps ของ win8 ที่ Design เด็จๆหน่อยซิครับหา inspiration
ถ้าเอา Inspiration ลองดูบทความนี้ของ MS ครับ
ตาลายเรยทีเดียว - -