共用方式為


本文章是由機器翻譯。

JavaScript

在 Windows 市集應用程式中以 JavaScript 建置和使用控制項

Chris Sells
Brandon Satrom

下載代碼示例

在上一篇文章中,"資料繫結在 Windows 存儲應用程式與 JavaScript,"我們挖到 Windows 庫中的 JavaScript (WinJS),並支援資料繫結。在使用資料繫結時,往往是在控制項,這就是為什麼我們花那麼多時間挖成照料和餵養 ListView 控制項的上下文中 (您可以看到在這條 msdn.microsoft.com/magazine/jj651576)。在本文中,我們將向您採取快速流覽可用的控制項,作為構建 Windows 存儲應用程式的 JavaScript 程式師。而且,如果這些控制項不能滿足您的需要,我們將介紹如何生成您自己。

當使用 JavaScript 生成控制項在 Windows 應用程式商店,你幾個家庭中有對控制項的訪問:

  • HTML5 元素:HTML5 元素是意義上它們是可重複使用大塊的 UI 和行為,例如,控制項 <progress/> 和 <a/>。
  • WinRT 控制項:控制項作為 Windows 運行時 (WinRT) 類公開投影到 JavaScript,如 Windows.UI.Popups.PopupMenu。
  • WinJS 控制項:作為 JavaScript 類如 WinJS.UI.ListView 實現的控制項。
  • CSS 樣式:CSS 提供了允許您佈置你的內容項,好像它們是控制項容器,例如,列數的幾個樣式: 4.

在本文中,我們將重點介紹控制項的前三個類別。

HTML5 元素

因為 Windows 存儲應用程式使用 JavaScript 構建基於 Web 技術,所有 HTML5 元素工作就好,作為圖 1 顯示。

HTML5 Controls Available to Your Windows Store Apps Built with JavaScript
圖 1 HTML5 的可用到您的 Windows 存儲應用程式使用 JavaScript 生成控制項

HTML5 元素的詳細資訊超出了本文討論的範圍,但我們建議你友好的鄰居 HTML5 文檔以瞭解更多資訊。另外,用於創建的示例圖1提供附帶的來原始程式碼下載。

WinRT 控制項

Windows 運行時提供了各種各樣的功能在所有種類的領域,但對於控制項,它提供了只有兩個:

  • 消息的對話方塊:具有可選標題的消息。
  • 彈出功能表:限於六個或更少項的功能表。

使用 MessageDialog 函數來調用消息對話方塊中:

var popups = Windows.UI.Popups;
var mb = new popups.MessageDialog("and welcome to my message box!", "Hello!");
mb.showAsync();

MessageDialog 類有一個返回一個承諾,就像所有其他非同步作業使用 JavaScript 生成 Windows 存儲應用程式有支配的 showAsync 方法。 在這種情況下,但是,我們忽略承諾因為我們往往不在意當一個消息對話方塊就會消失。 圖 2 顯示 (使用"訊息方塊,"這是 MessageDialog 的上一個術語) 的結果。

The WinRT Message Dialog
圖 2 WinRT 消息對話方塊

同樣使用彈出功能表類:

var popups = Windows.UI.Popups;
var menu = new popups.PopupMenu();
menu.commands.push(new popups.UICommand("one", null, 1));
menu.commands.push(new popups.UICommand("two", null, 2));
menu.showAsync({ x: 120, y: 360 }).done(function (e) {
  // Do something with e.label and/or e.id
  ...
});

在此示例中,創建一個彈出功能表中的物件之後, 我們提供兩個 UICommand 物件,每個都有一個標籤和可選的回檔和 id 參數。 我們因為我們要捕獲的事件參數中的"完成"完成方法不使用回檔的每個在此示例中的命令。 一個彈出式功能表,看起來像你所期望的如中所示圖 3

The WinRT Pop-up Menu
圖 3 WinRT 彈出功能表

請記住寫作時,內容功能表僅限於只有六個專案。

WinJS 控制項

雖然 HTML5 控制項是豐富多彩的集不會可擴展,直到全球資訊網協會決定添加新的元素標記和瀏覽器供應商決定來實現它。 同樣,WinRT 控制項的一組也是不可擴展 (雖然您可以生成非-UI Windows 運行時元件)。 可擴展的一組專門設有記住 Windows 存儲應用程式的控制項,用於最拿手的是由 WinJS 提供一組。

WinJS 控制項是提供某些簽名的建構函式中的 JavaScript 在實施一個控制項:

function MyControl(element,
    options) {...}

元素參數是意味著作為主機上的控制項中的內容,常常專區的 HTML 文件物件模型 (DOM) 元素 JavaScript 物件,該物件用於提供可選配置參數如 ListView itemDataSource 屬性選項參數。

若要查看 WinJS 控制項在行動中的,讓我們考慮一個 div,意味著作為 DatePicker 控制的主機:

  <div id="datePickerDiv"></div>

這個地方,我們可以作為這輕鬆地創建 DatePicker:

var datePicker = new WinJS.UI.DatePicker(datePickerDiv);

輸出是一個全新的 DatePicker 控制項,如中所示圖 4

Output of the DatePicker Control
圖 4 輸出的 DatePicker 控制

如果我們想要配置的控制,我們可以通過在一組選項中:

var datePicker = new WinJS.UI.DatePicker(datePickerDiv, { current: "6/2/1969" });

當前選項對於 DatePicker,讓我們設置的當前顯示的日期,如中所示圖 5

Setting the Currently Displayed Date
圖 5 設置當前所顯示的日期

一旦你與你的 HTML5 元素關聯的控制項,您可以抓取使用 winControl 屬性的控制項:

var datePicker = datePickerDiv.winControl; // Magical well-known property name
datePicker.current = "5/5/1995"; // Now we're talking to the control

進一步,一旦你該控制項,您可以回到與元素屬性關聯的 HTML5 元素:

var datePickerDiv = datePicker.element;
datePickerDiv.style.display = "none";
// Now we're talking to the HTML element

除了允許以程式設計方式創建,每個控制項還提供資料贏控制項和資料贏的選項屬性,通過聲明性創造我們已經看到:

  <div id="datePicker2"
    data-win-control="WinJS.UI.DatePicker" data-win-options=
    "{current: '6/2/1969'}" ></div>

資料贏控制項屬性是要調用的建構函式的名稱。 在資料繫結,其中需要調用 WinJS.Binding.processAll 贏將資料繫結屬性要分析 (見我們以前的文章),資料贏控制項屬性需要對它進行分析和要創建的控制項調用 WinJS.UI.processAll。 這就是為什麼您會看到 WinJS.UI.processAll 中的所有生成的專案範本代碼調用。

資料-贏-選項字串分析為較強大的 JavaScript 物件初始化語法中。 例如,您會發現而不是通過創建日期物件設置 DatePicker 控制項的當前選擇,我們傳遞的字串直接。 這是因為選項分析器不懂"new"關鍵字 — — 它只適用于靜態資料。 但是,因為期待 DatePicker 和其他 WinJS 控制項以聲明方式創建,他們作出的限制選項語法分析器,特別津貼的 — — 在本例中為 DatePicker — — 意味著在一個字串和解析它作為一個 Date 物件,那麼您。

每個控制項具有一組不同的選項,以及我們會參考你說明文件,以查看哪些控制項具有哪些選項。 圖 6 顯示的內置 WinJS 控制項的清單。

圖 6 WinJS 控制項

姓名 描述 類別
應用程式欄 在工具列中顯示應用程式級別的命令 WinJS.UI.AppBar
日期選擇器 顯示一個使用者介面,選取日期 WinJS.UI.DatePicker
翻轉視圖 通過一組的內容,一次一個專案翻轉 WinJS.UI.FlipView
飛出 顯示與任意內容覆蓋 WinJS.UI.Flyout
? 顯示項的集合中清單或網格,進行分組或取消分組 WinJS.UI.ListView
評分 顯示 UI 打分東西,例如,一部電影 WinJS.UI.Rating
語義縮放 提供放大從一個 ListView 到另一個,例如,縮小到組清單群組清單視圖的使用者介面 WinJS.UI.SemanticZoom
設置彈出 為應用程式設定的配置提供了一個使用者介面 WinJS.UI.SettingsFlyout
時間選擇器 顯示一個使用者介面來選擇時間 WinJS.UI.TimePicker
切換開關 顯示兩個選項之間選擇的使用者介面 WinJS.UI.ToggleSwitch
工具提示 (富) 顯示帶有任意 HTML 內容的工具提示 WinJS.UI.Tooltip
視圖框 提供縮放到可用空間的大小邏輯上固定區域 WinJS.UI.ViewBox

圖 7 WinJS 控制項顯示在行動中。

The WinJS Controls in Action
圖 7 中行動的 WinJS 控制項

您應該隨意混合和匹配 HTML5 控制項、 WinRT 控制項和 WinJS 在您的 Windows 存儲應用程式中的控制項。

或者,如果您沒有找到您需要對 HTML5、 Windows 運行時或 WinJS 所提供的清單中的控制項,您可以構建您自己。

自訂控制項

正如我們所提到的 WinJS 控制項是只提供以下形式的建構函式的函數:

function MyControl(element, options) {...}

建立這樣的控制項作為第一個參數傳遞執行函數創建的 HTML 父元素下的事項和使用的選項物件作為第二個參數傳遞。 例如,假設我們要建造如中所示的小時鐘控制項圖 8

A Custom Clock Control
圖 8 自訂時鐘控制項

假定我們有一個 div,所有設置為包含我們時鐘控制項:

  <div id="clockControl1"></div>

我們想就像 WinJS 的內置控制項,可以創建自訂控制項的實例就像這樣:

var clock = new Samples.UI.ClockControl(clockControl1, { color: 'red' });
clock.color = 'red'; // Can set options as part of construction or later

我們選擇了為我們的自訂控制項的名稱是 ClockControl Samples.UI 命名空間中。 正如之前,創建控制項是物質傳遞中包含的元素 (clockControl1) 和一組可選的選項的名稱/值對。 如果我們想要更改控制項的選項中的一個控制項的存留期內,在晚些時候我們應該能夠做到通過設置單個屬性值。

我們還想要能夠以聲明方式創建自訂控制項:

    <script src="/js/clockControl.js"></script>
      ...
    <div id="clockControl2"
        style="width: 200px; height: 200px;"    
        data-win-control="Samples.UI.ClockControl"
        data-win-options="{color: 'red'}">  </div>

作為我們執行的一部分,我們想確保 winControl 和元素屬性設置,私有成員正在進行相應的標記,並可以適當地處理事件。 當我們挖到 ClockControl 的執行情況,我們會看到 WinJS 如何説明我們實現這些功能。

控制類第一,我們需要確保 ClockControl 會使其成為正確的命名空間。 大多數現代語言有概念的命名空間作為一種避免碰撞分離到單獨的命名區域的類型、 函數和值的方式。 例如,如果 Microsoft 提供的 WinJS 2.0 中的 ClockControl 類型,會在 WinJS.UI 命名空間,所以它不會與 Samples.UI 碰撞。 在 JavaScript 中,命名空間是只是另一個物件的建構函式、 函數和值,這樣,您可以使用填充:

// clockControl.js
(function () {
  // The hard way
  window.Samples = window.Samples || {};
  window.Samples.UI = window.Samples.UI || {};
  window.Samples.UI.ClockControl = 
    function(element, options) { ...
};
})();

這只是正常。 但是,定義命名空間 (和嵌套命名空間) 是這種共同的事要做 WinJS (像許多 JavaScript 庫) 提供了一個快捷方式:

// clockControl.js
(function () {
  // The easy way
  WinJS.Namespace.define("Samples.UI", {
    ClockControl: function (element, options) { ...
};
  };
})();

WinJS.Namespace 命名空間中的定義函數允許定義一個新的命名空間,妥善處理的虛線名稱為您解析。 第二個參數是要定義的建構函式,函數和我們想要此命名空間中,這是只是在我們的例子中的 ClockControl 建構函式從公開的值的物件。

控制項的屬性和方法我們 ClockControl 類型上我們想公開方法和屬性,如顏色屬性。 這些方法和屬性可以是實例或靜態的它們可能公共或私人 (至少為"私有"作為 JAVA­腳本允許要獲取的物件的成員)。 通過正確使用建構函式的原型屬性和 JavaScript 的新的 Object.defineProperties 方法支援所有這些概念。 WinJS 提供一個快捷方式,也通過 WinJS.Class 命名空間中的定義方法:

WinJS.Namespace.define("Samples.UI", {
  ClockControl: WinJS.Class.define(
    function (element, options) {...}, // ctor
  { // Properties and methods
    color: "black",
    width: { get: function () { ...
} },
    height: { get: function () { ...
} },
    radius: { get: function () { ...
} },
    _tick: function () { ...
},
    _drawFace: function () { ...
},
    _drawHand: function (radians, thickness, length) { ...
},
  })
});

WinJS.Class.define 方法採用作為建構函式,該函數,但它也需要的一組屬性和方法。 定義方法知道如何創建屬性的 get 和 set 函數提供。 進一步,它知道加上底線首碼的屬性或方法 — — 例如,_tick — — 要被"私有"。JavaScript 真的不支援傳統意義上的私有方法 — — 就是,我們仍然可以調用 _tick 方法。 但是,他們不會顯示在 Visual Studio 2012 智慧感知或 JavaScript 的-在迴圈中,這是信號他們並不意味著大眾消費至少一種簡便方法。

建構函式設置需將 WinJS 控制項,如中所示的屬性圖 9

圖 9 建構函式設置的屬性必須是 WinJS 控制項

WinJS.Namespace.define("Samples.UI", {
  ClockControl: WinJS.Class.define(function (element, options) {
    // Set up well-known properties
    element.winControl = this;
    this.element = element;
    // Parse the options; that is, the color option
    WinJS.UI.setOptions(this, options);
    // Create the drawing surface
    var canvas = document.createElement("canvas");
    element.appendChild(canvas);
    this._ctx = canvas.getContext("2d");
    // Draw the clock now and every second
    setTimeout(this._tick.bind(this), 0);
    setInterval(this._tick.bind(this), 1000);
  },
  ...
});

建構函式做的第一件事是設置著名的 winControl 和元素屬性,以便開發人員可以承載的 HTML5 元素和 JavaScript 控制項之間來回跳轉。

接下來,該建構函式處理選項。 您也許還記得選項可以指定為名稱/值對的集合或 — — 使用來自 HTML5 的資料贏的選項屬性 — — 一個字串。 WinJS 處理解析選項字串的 JavaScript 物件,以便您可以只是處理的名稱/值對。 如果你願意,你可以拉出單個屬性,例如,在我們的例子中的顏色屬性。 但是,如果您有一個大型的選項清單,WinJS.UI 命名空間中的 setOptions 方法將遍歷所有的選項物件中的屬性和設置它們作為屬性控制項。 例如,下面塊是代碼的等效的:

// Setting each property one at a time
myControl.one = "one";
myControl.two = 2;
// Setting all properties at once
WinJS.UI.setOptions(myControl, {
  one: "one",
  two: 2,
});

設置控制項的選項之後, 是建構函式的工作來創建任何子項目,HTML5 父元素,它需要完成的工作。 在 ClockControl,我們使用 HTML5 畫布元素和一個計時器。 此控制項執行是只是純舊 HTML 和 JavaScript,因此它並不這裡所示 (但在附帶的代碼下載中可用)。

控制事件控制的方法和屬性,除了經常公開事件。 事件是從一些有趣的事情發生了,你控制的一些通知,如使用者按一下控制項上或控制項已達到某種狀態,觸發某種其他類型的程式中的行為。 基於 HTML DOM 的榜樣,你要想方法,如 addEventListener 和 removeEventListener,以允許開發人員無論事件訂閱您的控制項公開以及相應的 onmyevent 屬性。

例如,如果我們想要將從我們的樣本 ClockControl 事件暴露每隔 5 秒鐘,我們希望能夠以程式設計方式向其訂閱:

    // Do something every 5 seconds
    window.clockControl_fiveseconds = function (e) {
      ...
    };
    var clock = new Samples.UI.ClockControl(...);
    // This style works
    clock.onfiveseconds = clockControl_fiveseconds;
    // This style works, too
    clock.addEventListener("fiveseconds", clockControl_fiveseconds);
    Declaratively, we’d like to be able to attach to custom events, too:
    <!-- this style works, three -->
    <div data-win-control="Samples.UI.ClockControl"
      data-win-options="{color: 'white',
        onfiveseconds: clockControl_fiveseconds}" ...>
    </div>

啟用這些樣式的所有三個需要兩個條件:管理事件訂閱者法 (和調度事件發生時),並為每個事件的屬性。 這兩個均由 WinJS.Class 命名空間:

// clockControl.js
...
WinJS.Namespace.define("Samples.UI", {
  ClockControl: WinJS.Class.define(...);
});
// Add event support to ClockControl
WinJS.Class.mix(Samples.UI.ClockControl, 
  WinJS.UI.DOMEventMixin);
WinJS.Class.mix(Samples.UI.ClockControl,  
  WinJS.Utilities.createEventProperties("fiveseconds"));

WinJS.Class 的混合方法允許您在屬性和方法提供的現有物件中混合使用。 在這種情況下,從 WinJS.UI DOMEventMixin 提供了三種方法:

// base.js
var DOMEventMixin = {
  addEventListener: function (type, listener, useCapture) {...},
  dispatchEvent: function (type, eventProperties) {...},
  removeEventListener: function (type, listener, useCapture) {...},
};

一旦我們從 DOMEventMixin 混合使用的方法,我們可以為每個使用 WinJS.Utilities 的 createEventProperties 方法創建的物件的混合方法的自訂事件創建屬性。 此方法會產生您傳遞中,前面加"on"首碼,以逗號分隔的事件名稱的每個事件方法的集合。 設置此屬性和方法提供的這些兩對組合方法調用的我們已經增加我們支援 fiveseconds 事件的自訂控制項。 派遣從內部控制這種類型的事件,我們調用 dispatchEvent 方法:

// clockControl.js
...
_tick: function () {
  var now = new Date();
  var sec = now.getSeconds();
  ...
// Fire the 5 second event
  if (sec % 5 == 0) {
    this.dispatchEvent("fiveseconds", { when: now });
  }
},
...

電話 dispatchEvent 採用兩個參數:事件和可選的詳細資訊的名稱物件可用在事件本身。 我們經過在單一的"時"值,但正在 JAVA 的 JavaScript­腳本中,我們可以通過我們想要的一切。 訪問事件處理常式中的詳細資訊是拔出詳細的事件物件本身價值的事項:

// Do something every 5 seconds
window.clockControl_fiveseconds = function (e) {
  var when = e.detail.when;
  ...
};

確定我們已經表明您的 WinJS 控制項的原則 — — 在命名空間中定義的類、 設置的 winControl 和元素的屬性、 處理的選項物件、 定義屬性和方法,和定義和調度的自訂事件 — — 是在 Microsoft 用於生產 WinJS WinJS 團隊控制項本身的確切相同的技術。您可以瞭解有關您喜愛的控制項通過閱讀提供 WinJS 的 ui.js 檔的形成原理的很多。

Chris Sells 是在 Telerik 的開發者工具司的副總裁。他是"建築 Windows 8 的應用程式與 JavaScript"(艾迪生 - 衛斯理專業、 2012年)、 中國智慧財產權報從這篇文章被改編的。銷售,有關的詳細資訊和他不同的計畫,是可在 sellsbrothers.com

Brandon Satrom 是一個程式管理器在劍道 UI 司在 Telerik.他是"建築 Windows 8 的應用程式與 JavaScript"(艾迪生 - 衛斯理專業、 2012年)、 中國智慧財產權報從這篇文章被改編的。您可以按照他在 Twitter 上 twitter.com/BrandonSatrom

由於下面的技術專家對本文的審閱:克裡斯 · 安德森、 喬納森 · 安東莞、 邁克爾 · 魏因哈特、 肖恩 · 維爾德穆特和喬什 · 威廉斯