Share via


Windows 市集應用程式實作手冊 - 使用 JavaScript : Lab 03

實驗 3 : 搜尋和分享

概述

常用工具列是 Windows 8 使用者經驗當中很關鍵的一項功能。您只要刷一下螢幕畫面或按壓視窗鍵 + C ,這些按鈕(「常用工具列」)就會從螢幕畫面的右邊滑進來並提供一些橫跨Windows 8應用程式的常用功能。舉例來說,如果您要在某一個應用程式裡實作搜尋,您只要選擇搜尋快速鍵並在搜尋窗格內鍵入一個搜尋用詞即可,因為每一個應用程式裡的使用者介面 – 和叫用該使用者介面所需要的動作 – 都是相同的。如果您想與另一個應用程式分享資料,只要選擇分享快速鍵就行;支援「分享」的應用程式就會讓您分享資料。舉例來說,小畫家應用程式就能分享圖畫,或 Contoso 食譜就會與其他支援分享的應用程式分享某一項食材配方。

在本實驗裡,您將為 Contoso 食譜新增「搜尋」和「分享」、您將取得實作「搜尋」和「分享」協定的第一手經驗、您也將學習得知這些協定如何在兩個應用程式之間或應用程式和 Windows 之間提供更高層次的整合。

目標

本實驗將引導您如何:

  • 實作「分享」於 Windows 8 應用程式。

  • 實作「搜尋」於 Windows 8 應用程式。

  • 實作「搜尋」建議。

系統需求

要完成本實驗,您必須擁有下列東西:

  • Microsoft Windows 8

  • Microsoft Visual Studio 2012

設定

為了讓您的電腦能進行本實驗,您必須先執行下列步驟:

  1. 安裝 Windows 8。

  2. 安裝 Microsoft Visual Studio 2012 。

練習

本動手做實驗室包含下列練習:

  1. 新增食譜分享

  2. 新增食譜搜尋

完成本實驗,估計需要費時: 30 到 40 分鐘。

練習 1 : 新增食譜分享

在練習 1 裡,您將新增「分享」支援到 Contoso 食譜內,以使食譜配方能與其他應用程式分享。您將分享兩種類型的資料:文字資料(包括配方名稱、食材原料、和用法說明)以及影像資料(包含代表該食譜配方的圖像)。

任務 1 - 叫用分享快速鍵

首先,讓我們看見分享快速鍵被叫用到 Contoso 食譜裡會有哪些行為表現,然後再來新增「分享」支援。

  1. 在 Visual Studio 內,打開您在實驗 2 已完成的 ContosoCookbook 專案。如果您尚未完成實驗 2 或想啟動另外的參考複本,您可以在本實驗的起始材料裡找到一份完整的版本。
  2. 請按壓 F5 來啟動 Contoso 食譜。
  3. 點擊任一食譜項目來展開項目明細頁。
  4. 從螢幕的右邊邊緣向左邊刷一下或按壓視窗鍵 + C 來顯示常用工具列。
  5. 點擊分享快速鍵來展示「分享」窗格。
  6. 由於 Contoso 食譜目前尚未實作「分享」協定,所以,分享窗格會告訴您「此應用程式無法分享。」
  7. 返回 Visual Studio 並停止偵錯。

任務 2 – 實作食譜分享

現在,您已經看過了應用程式不支援「分享」時分享窗格的模樣。接下來,讓我們將分享協定加到 Contoso 食譜裡,以便讓它能分享食譜配方資料。

  1. 打開 itemDetail.js 並在靠近頂部的「文件」之 "use strict" 陳述式後面新增下列陳述式。

    JavaScript
      var storage = Windows.Storage;
      var dtm = Windows.ApplicationModel.DataTransfer.DataTransferManager;
      var item;

  2. 刪除 ready 函式第一行裡的 "var" ,使這一行看起來像這個樣子。

    item = options && options.item ? Data.resolveItemReference(options.item) :
    Data.items.getAt(0);

  3. 新增下列程式碼到 ready 函式的底部。

    JavaScript
    // Register for datarequested events for sharing
    dtm.getForCurrentView().addEventListener("datarequested", this.onDataRequested);

  4. 最後,新增下列函式於 ready 函式後面(注意:您必須在 ready 函式右大括號後面加上一個逗號)。

    JavaScript
    onDataRequested: function (e) {
    var request = e.request;
    request.data.properties.title = item.title;
    request.data.properties.description = "Recipe ingredients and directions";

    // Share recipe text
    var recipe = "\r\nINGREDIENTS\r\n" + item.ingredients.join("\r\n");
    recipe += ("\r\n\r\nDIRECTIONS\r\n" + item.directions);
    request.data.setText(recipe);
    },

    unload: function () {
    WinJS.Navigation.removeEventListener("datarequested", this.onDataRequested);
    }

    備註:在登錄 DataTransferManager 的 DataRequested 事件處理常式後,您就能實作分享。當使用者選擇分享快速鍵時,就會觸發這些事件。在這個例子裡,您回應該事件的方式是呼叫 setText 的 DataPackage 物件,物件就透過 e.request.data 被公開出來並以文字形式來提供食譜配方,唯顯示在分享窗格裡的分享目標只限於能運用文字來展示的分享目標。

  5. 請按壓 F5 來啟動應用程式。

  6. 點擊任一食譜配方來展現食譜明細頁。

  7. 顯示常用工具列並選擇分享快速鍵來展示分享窗格。現在,分享窗格顯示出一長串的分享目標,它們都是安裝在您的裝置上可運用您的分享來源之分享資料的應用程式。

    備註:如果您還沒有安裝分享目標範例,現在應該是最佳時機,可以安裝 Windows 8 SDK 範例包裡的分享目標範例了。分享目標範例應用程式會演示如何編寫分享目標應用程式。更重要的是,它提供了一個分享目標,可以用來測試您所開發的「分享來源」應用程式。此分享目標接受影像、文字、和其他類型的資料。要安裝分享目標範例於系統中,請在 Visual Studio 中打開它並執行一次。此後,每當您從任何 Windows 市集應用程式中選擇分享快速鍵時,它應該都會出現在分享目標列表中。

  8. 選擇分享窗格當中任何一個分享目標,確認它已接收到食譜配方文字。圖 1 顯示已接收到 Contoso 食譜分享的食譜配方文字後的 Windows 8 SDK 分享目標範例應用程式。

    圖 1
    顯示分享食譜的分享目標範例應用程式

  9. 返回 Visual Studio 並停止偵錯。

任務 3 – 實作食譜影像分享

Contoso 食譜現在已能分享食譜配方的文字資料,但是,每一份食譜配方都包含一張圖像,它應該也可以分享食譜影像才對。如此一來,接受影像的分享目標才能同時顯現食譜配方的照片和文字(假設分享目標支援文字和影像)。讓我們修改您的分享程式碼來支援點陣圖( bitmap )影像和文字。

  1. 在  itemDetail.js 裡,進到您在任務  2 所新增的 DataRequested 函式。

  2. 新增下列數行程式碼到此函式的後面。

    JavaScript
    // Share recipe image
    var uri = item.backgroundImage;
    if (item.backgroundImage.indexOf("http://") != 0)
    uri = "ms-appx:///" + uri;

    uri = new Windows.Foundation.Uri(uri);
    var reference = storage.Streams.RandomAccessStreamReference.createFromUri(uri);
    request.data.properties.thumbnail = reference;
    request.data.setBitmap(reference);

  3. 請按壓 F5 來啟動此應用程式。

  4. 點擊任一食譜配方來展現食譜明細頁。

  5. 顯示出常用工具列,並選擇分享快速鍵來展示分享窗格。

  6. 在分享窗格裡,選擇任何一個分享目標並驗證它已接收到食譜配方圖像。圖 2 顯示的分享目標範例應用程式,為已接收到 Contoso 食譜所分享的食譜配方圖像後的模樣。


    圖 2
    顯示分享食譜 圖像的分享目標範例應用程式

  7. 返回 Visual Studio 並停止偵錯。

練習 2 :新增食譜搜尋

在練習 2 裡,您將新增「搜尋」支援到 Contoso 食譜內,以便使用者可以使用搜尋快速鍵來搜尋食譜配方資料。舉例來說,使用者想找出所有含糖的食譜配方,那麼,他 / 她就可以叫用搜尋快速鍵並在搜尋方格內鍵入「 sugar 」。如此一來,含糖食譜配方就會列表展現在眼前。

任務 1 – 叫用搜尋快速鍵

在新增「搜尋」支援到 Contoso 食譜之前,且讓我們看看搜尋使用者介面被叫用的模樣,這時候, Contoso 食譜是前台應用程式。

  1. 請按壓 F5 來啟動應用程式。
  2. 從螢幕右邊邊緣向左邊刷或按壓視窗鍵 + C 來顯示常用工具列。
  3. 點擊搜尋快速鍵來展示搜尋窗格。
  4. 在搜尋方格裡,鍵入「 sugar 」(不帶引號)並按壓輸入( Enter )或點擊搜尋方格右邊的放大鏡圖標。
  5. Windows 8 會告訴您「這個應用程式無法被搜尋。」但是,只要您新增「搜尋」支援到 Contoso 食譜內,這種情況就會改變。
  6. 返回 Visual Studio 並停止偵錯。

任務 2 – 新增「搜尋」支援

要實作搜尋,您需要為您的應用程式編寫搜尋協定程式碼。不過, Visual Studio 會為您做絕大部份的工作;它會將 JavaScript 協定插入您的應用程式裡。您只需要拿捏調適此 JavaScript ,讓它能在您的應用程式裡做特定領域的資料搜尋。方法很簡單,您只要做好接下來的幾個步驟即可。

  1. 用滑鼠右鍵單擊方案總管裡的 page 資料夾,再使用加入 > 新增資料夾命令來新增命名為「 search 」的資料夾到 pages 資料夾內。

  2. 用滑鼠右鍵單擊此「 search 」資料夾,並使用加入 > 新增項目命令來新增一個命名為 search.html 的搜尋目標物協定,如圖 3 所示。

    圖 3
    新增一份搜尋協定

  3. 新增下列陳述式到 default.html ,以確保啟動此應用程式時, search.js 會被載入。

    HTML
    <script src="/pages/search/search.js"></script>

  4. 打開 search.js 並找到 searchData 函式。這是使用者從搜尋快速鍵啟動「搜尋」時所呼叫的那部份搜尋協定。您需要修改這個函式的程式碼,以便實作食譜搜尋。要這麼做,請找出 _searchData 函式並以如下所示的「搜尋」來替換呼叫標題、副標題和描述的 indexOf 之陳述式。

    JavaScript
    return (item.title.indexOf(queryText) >= 0 ||
    item.directions.indexOf(queryText) >= 0);

    備註:您剛剛所做的變更會讓 Contoso 食譜搜尋每一份食譜配方的標題和用法說明之屬性,而且是根據使用者在搜尋方格內所輸入的文字來這麼做。該文字會被傳遞到命名為 queryText 的參數之 searchData 函式。如果您要擴充搜尋,使包括其他食譜配方屬性,這兒正是您該採取行動的地方。

  5. 在仍然處於 search.js 的情況下,找到 _itemInvoked 函式。此函式會被呼叫出來,每當使用者在顯示搜尋結果的 ListView 裡選擇任何一個項目時。新增下列程式碼到 _itemInvoked 的 _itemPromise.done 函式之處理常式。

    JavaScript
    nav.navigate("/pages/itemDetail/itemDetail.html ", { item:
    Data.getItemReference(item.data) });

  6. 打開 Search.html ,其包含一 HTML 片段,用以定義搜尋結果應如何展現給使用者。找到類別( class )是 "item" 的 DIV ,進到裡面去找出類別為 "item-content" 的 DIV ,使用底下的陳述式來替換該 DIV 的內容 – 一個 H3 元素和兩個 H4 。

    HTML
    <h3 class="item-title win-type-ellipsis" data-win-bind="innerHTML: shortTitle search.markText"></h3>
    <h4 class="item-subtitle win-type-x-small win-type-ellipsis">
    Preparation time: <span data-win-bind="textContent: preptime"></span>
    minutes
    </h4>

  7. 打開 Search.css 。找到 ".search section[role=main] .resultslist .item" 和修改 the-ms-grid-columns 行,如下所顯示,並請一併修改寬度屬性。

    CSS
    .search section[role=main] .resultslist .item {
    /* Define a grid with columns for an icon and item details */
    -ms-grid-columns: 62px 1fr;
    -ms-grid-rows: 1fr;
    display: -ms-grid;
    height: 64px;
    padding-left: 7px;
    padding-top: 1px;
    padding-right: 7px;
    width: 340px;
    }

  8. 找到 ".search section[role=main] .resultslist .item .item-image" ,並變更寬度為 60px 和高度為 45px ,使食譜影像保持原始的縱橫比。

    CSS
    .search section[role=main] .resultslist .item .item-image {
    -ms-grid-column: 1;
    -ms-grid-row: 1;
    height: 45px;
    margin-top: 5px;
    width: 60px;
    }

  9. 請按壓 F5 來啟動此應用程式。

  10. 顯示常用工具列。

  11. 點擊搜尋快速鍵來展示搜尋窗格。

  12. 鍵入「 sugar 」(不含引號)到搜尋窗格上方的搜尋對話框內,再按壓輸入(Enter)或點擊搜尋方格右邊的放大鏡圖標。

  13. 驗證六個食譜配方出現在搜尋結果裡。(如圖 4 )

    圖 4
    「 sugar 」的搜尋結果

  14. 選擇任一食譜配方並驗證食譜細節出現在畫面。

  15. 返回 Visual Studio 並停止偵錯。

任務 3 – 精緻化搜尋結果頁

到目前為止,一切令人滿意!在 Visual Studio 為您新增搜尋協定後,您取得了許多免費而且強大的功能。經過一些小修改之後, Contoso 食譜也能進行搜尋了。不過,您有沒有注意到出現在搜尋結果頁面上方那些奇怪的命名?它們顯示的是 "Group 1" 、 "Group 2+" … 等等,而不是直接顯示群組名稱,例如「中國菜( Chinese )」和「義大利菜( Italian )」。讓我們簡單修改一下 search.js ,來解決這個問題。

  1. 打開 search.js ,到「文件」頂部附近去找以  _generateFilters 方法寫著 "TODO: Replace or remove example filters" 的那一小段註解。

  2. 使用底下這些陳述式來替換該註解底下的兩行程式碼(兩次 this._filters.push 的呼叫)。

    JavaScript
    Data.groups.forEach(function (group) {
    this._filters.push({ results: null, text: group.title, predicate: function (item) { return item.group.key === group.key; } });
    }, this);

    備註:這些陳述式會以您的應用程式內的食譜群組名稱來替換 Visual Studio 所生成的寫死的群組名稱。

  3. 再度啟動應用程式,重複「 sugar 」的搜尋。驗證一下:頁面頂部的通用群組名稱已經被食譜群組名稱所替換,如圖 5 所示。

    圖 5
    以食譜群組標題呈現的搜尋結果

  4. 返回 Visual Studio 並停止偵錯。

任務 4 – 新增「搜尋」建議

最後,您還可以為搜尋經驗新增一些「畫龍點睛」的強化效果,那就是,提供一些建議,以供使用者在搜尋方格鍵入搜尋用詞時參考。做法很簡單;您只要為 SuggestionsRequested 事件新增一道處理常式而已。作法如下。

  1. 打開 search.js ,在「文件」底部附近新增下列函式(在 onquerysubmitted 事件處理常式的後面)。

    JavaScript
    appModel.Search.SearchPane.getForCurrentView().onsuggestionsrequested = function (eventObject) {
    var text = eventObject.queryText.toLowerCase();
    var terms = ["salt", "pepper", "water", "egg", "vinegar", "flour", "rice", "oil"];

    terms.forEach(function(term) {
    if (term.indexOf(text) == 0) {
    eventObject.request.searchSuggestionCollection.appendQuerySuggestion(term); }
    });
    };

    備註:您剛剛新增的程式碼,將提供一些匹配鹽( salt )、胡椒粉( pepper )、水( water )、蛋( egg )、醋( vinegar )、麵粉( flour )、米( rice )、糖( sugar )和油( oil )等字型的搜尋建議。如果使用者鍵入 "sa" ,搜尋窗格內就會出現 "salt" 這個完整的建議用字。當然,只要您喜歡,您可以隨意新增更多建議。譬如,您想讓「番茄醬」( ketchup )出現在使用者鍵入 "ke" 時,那麼,就將該用詞新增列表裡吧。

  2. 再度啟動此應用程式並在搜尋方格內鍵入 "pep" 。驗證一下: "pepper" 已出現在搜尋方格下面的建議列表中,如圖 6 所示。

    圖 6
    運作中的搜尋建議

  3. 返回 Visual Studio 並停止偵錯。

摘要

協定是 Windows 8 很重要的一部份,因為它們允許應用程式與視窗介面( shell )整合並提供一致而且可預見的使用者體驗。這種鬆散耦合的協作具有很高的綜效性和可擴展性,讓您可以與任何應用程式分享任何東西、在任何應用程式裡做搜尋 … 等等。

在本實驗裡,您親身學習了「分享」和「搜尋」這兩種類型的協定。在稍後的實驗裡,您將使用 另一類型的協定來與設定( Settings )常用工具列做整合。但是,在這兒且讓我們先處理另一主題:媒體擷取( media captures ),也就是內建在大多數個人電腦和行動設備器具裡的鏡頭之使用。這是下一個實驗的主題,所以,讓我們繼續前進吧!

繼續下一個實驗