Win8:适用于 Windows 应用商店应用的 JavaScript 项目模板 (Windows)

来源:互联网 发布:崔永元 转基因 知乎 编辑:程序博客网 时间:2024/05/21 08:55


        本主题提供有关使用 JavaScript 为 Windows 构建的 Windows 应用商店应用的项目模板的深入信息。除每个模板的简单摘要外,还提供了有关导航模型、数据模型、视图状态处理的实施详细信息以及其他详细信息。许多这些实施详细信息适用于多个模板。

有关其他语言的 Visual Studio 模板和 Blend 模板的信息,请参阅使用模板立即开始你的应用(C#/VB/C++)

适用于 Windows 应用商店应用的网格项目模板

网格应用模板是开始创建 Windows 应用商店应用的一种非常有用的方法,你可以自定义该模板,以便用户能够通过浏览不同类别来找到他们所需的内容。例如购物应用、新闻应用、照片或视频应用。此模板使用为 Windows 应用商店应用建议的 JavaScript 导航模型。

网格应用默认显示一个主页,其中显示组列表。“组”表示指定的一组项目,比如一个包含各个零售项的虚拟部门商店分部。如果用户选择一个组,应用将打开该组的详细信息页面,并在该页右侧显示项列表。用户可以从主页或组详细信息页面中选择项。这将打开显示项详细信息的整页视图(下面是显示在顶部的页面)。

“网格”模板的项目文件

网格应用模板包含以下 HTML 文件:

  • default.html,该文件最先加载,并为内容主体(其中每个页面都加载进主窗口)提供标记。
  • groupedItems.html,这是主页。用户通过它可以查看组和项,或选择一个项以导航到整页项视图,或选择一个组标签以导航到组详细信息页面。
  • groupDetail.html,允许用户在左侧查看组详细信息,同时在右侧查看项,并选择一个项以导航到整页项视图。
  • itemDetail.html,某个项的整页视图。

该模板包含以下 JavaScript 文件:

  • default.js,指定当启动应用时应用的行为。
  • groupedItems.js,指定与主页相关联的行为。
  • groupDetail.js,指定与组详细信息页面相关联的行为。
  • itemDetail.js,指定与整页项视图相关联的行为。
  • navigator.js,实现适用于 Windows 应用商店应用 JavaScript 模板的导航模型。
  • data.js,这是数据源对象,它向应用的其余部分公开数据。

该模板包含以下 CSS 文件:

  • default.css,为内容主体页面和应用整体指定 CSS 样式。
  • groupedItems.css,为主页指定 CSS 样式。
  • groupDetail.css,为组详细信息页面指定 CSS 样式。
  • itemDetail.css,为整页项视图指定 CSS 样式。

网格应用模板还包含 package.appxmanifest 文件(该文件介绍用于 Windows 的应用包)和 PFX 文件(用于为 appxmanifest 文件签名并且此文件作为项目文件包含以支持从命令行构建)。该模板还包含一些图像文件,如用作初始屏幕图像的 splashscreen.png,以及用于 Windows 应用商店的 storelogo.png。

“网格”模板的工作原理

  • 常见的编码功能
  • 应用生命周期
  • 导航模型
  • 向项目模板中添加数据
  • 处理视图状态
  • CSS 样式

常见的编码功能

下列功能对所有项目模板都通用:

  • 每个 JavaScript 文件都将代码包装在自我执行匿名函数中,如下所示:

JavaScript

 
(function () {
    // . . .
})();
 

在匿名函数内部添加的成员是专用的,但你可使用 WinJS.Namespace.define函数将其公开。使用匿名函数会更改编写某些代码(例如当你添加自己的事件处理程序时)所需的方式。有关详细信息,请参阅对基本应用编码。

  • 各 JavaScript 文件使用“use strict”语句指定使用严格模式。有关详细信息,请参阅JavaScript 语言参考中的严格模式。
  • Default.js 包含对 WinJS.Binding.optimizeBindingReferences 的调用。此函数有助于防止在应用中使用声明性绑定时出现内存泄漏(模板中常见问题)。
  • 严格的声明性处理始终处于打开状态。你必须使用 WinJS.Utilities.markSupportedForProcessing 来指定函数可以使用声明性处理。

XML 文档注释在 JavaScript 文件中用在几个地方,用来提供更完整的 IntelliSense 体验。有关详细信息,请参阅JavaScript IntelliSense。

应用生命周期

应用生命周期的实现对于所有适用于 Windows 应用商店应用的JavaScript 项目模板而言都是相同的。应用生命周期在应用启动时开始,并在应用关闭时结束。项目模板包含一个用于管理应用生命周期的通用模式。当你创建基于项目模板的应用时,可能需要包含用于处理其他情况的代码,如当应用挂起或终止时处理数据的情况。

default.html 文件被设置为每个模板的起始页面。default.html对应的 JavaScript 文件包含以下对WinJS.Application.start的调用,该调用会启动应用事件的分发。

JavaScript

 
var app = WinJS.Application;
// . . .
app.start();
 

添加与应用生命周期管理相关的代码的最佳位置是在 default.js 中。default.js 的实现对所有项目模板而言都相同。此文件包含处理 WinJSonactivated 事件的代码。当发生 Windows 运行时激活时,将引发该事件。onactivated 事件处理程序中的代码会检查应用是否是从 Windows“开始”屏幕启动,并调用WinJS.UI.processAllprocessAll 函数加载在控件的 DIV 元素中包含data-win-control属性的所有控件。此处是包含processAll 函数的代码。

JavaScript

 
 
app.addEventListener("activated", function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
            // . . .
        } else {
            // . . .
        }
        // . . .
        }
        args.setPromise(WinJS.UI.processAll().then(function () {
            // The code in this section navigates to the current page, if one
            // is set, or the home page if a current page is not set.
            // . . .
        }));
    }
});
 

如果你的代码需在应用设置其初始状态时运行,则应将该代码包含在 WinJS onactivated 事件的处理程序中。如果应用在挂起之后已被重新激活,那么你可能需要包含其他代码。在代码注释指示的位置添加此代码。

JavaScript

 
 
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
    // TODO: This application has been newly launched. Initialize
    // your application here.
} else {
    // TODO: This application has been reactivated from suspension.
    // Restore application state here.
}
 
 

如前所述,模板不包含处理应用挂起的代码。要在你的代码中处理这种应用状态,可以在 WinJS oncheckpoint 事件处理程序中添加代码,如此处的 default.js 所示,也可添加代码来注册 Windows 运行时suspending 事件的(它将调用oncheckpoint)。

JavaScript

 
app.oncheckpoint = function (args) {
    // TODO: This application is about to be suspended. Save any state
    // that needs to persist across suspensions here. If you need to 
    // complete an asynchronous operation before your application is 
    // suspended, call args.setPromise().
    app.sessionState.history = nav.history;
};
 

你可以使用 WinJS 或 Windows 运行时事件,或者两者的组合来管理应用生命期。然而,WinJS 事件和函数对大多数应用而言已足够了。有关详细信息,请参阅如何挂起应用和如何恢复应用。

以下是与应用生命周期相关的一些 WinJS 事件和函数:

  • activated
  • loaded
  • ready
  • checkpoint
  • unload
  • sessionState

CSS 样式

模板的总体行为和外观由 CSS 样式表创建:ui-dark.css。下面是一个定义主要颜色主题、字体和其他样式属性的WinJS 样式表。项目引用在此处显示:

HTML

 
<linkhref="//Microsoft.WinJS.1.0/css/ui-dark.css"rel="stylesheet">
 

你可以在所有 HTML 页面中将此引用更改为引用ui-light.css,这是适用于 Windows 应用商店应用的建议备选颜色和样式主题:

HTML

 
<linkhref="//Microsoft.WinJS.1.0/css/ui-light.css"rel="stylesheet">
 

网格和拆分项目模板中的大多数 HTML 页面都使用一个或多个WinJS 模板(与 Visual Studio 项目和项模板不同)来设定格式并显示多个数据实例。例如,如果页面上显示一个ListView 控件,你将会找到一个类名为itemtemplate 的 WinJS 模板。类名用于在 JavaScript 文件中检索元素和指定 CSS。下面是拆分项目模板的 items.html 中的项模板:

HTML

 
<divclass="itemtemplate"data-win-control="WinJS.Binding.Template">
    <divclass="item">
        <imgclass="item-image"src="#"data-win-bind="src: backgroundImage; alt: title"/>
    <divclass="item-overlay">
        <h4class="item-title"
            data-win-bind="textContent: title"></h4>
        <h6class="item-subtitle win-type-ellipsis"
            data-win-bind="textContent: subtitle"></h6>
    </div>
</div>
 
 

要点  itemtemplate 模板适用于任何类型的ListView 项,根据上下文不同,该项可能是一个组或单个数据项。

与 HTML 页面及其 WinJS 模板相关联的 CSS 样式是限定范围的 CSS 样式。使用限定范围的样式可以限制对特定页面所应用的样式。这将有助于减少修复由于特定 CSS 样式源不清晰所导致的问题而花费的时间。以下是使用限定范围的样式的示例。items.css中的此部分代码显示为前一个项模板的 IMG 元素设置的 CSS属性。此元素表示ListView 中的每个项所关联的图像。

CSS

 
.itemspage .itemslist .item .item-image {
    -ms-grid-row-span: 2;
}
 
 

在上个示例中,itemspage 条目设置了样式的作用域,将 CSS 的应用范围限制为在 items.html 中声明的itemspage DIV 元素中的元素。itemslist 条目进一步将 CSS 限制为主页中的主要内容部分,等等。items.html 中的主要内容部分(声明ListView)如下所示:

HTML

 
<divclass="itemslist win-selectionstylefilled"
    aria-label="List of groups"
    data-win-control="WinJS.UI.ListView"
    data-win-options="{ selectionMode: 'none' }">
</div>
 
 

处理视图状态

“网格”模板和“拆分”模板等项目模板旨在处理一些视图状态,包括纵向、贴靠、全屏幕和填充。有关 Windows应用商店应用中的视图状态的详细信息,请参阅布局指南。网格和拆分模板处理项目模板导航模型中的视图状态。有关详细信息,请参阅导航模型。

导航控件(PageControlNavigator)在加载页面时传递位置(页面 URI)和状态,它还会使用相同方式传递有关视图状态的信息。首先,在 navigator.js 中,导航控件为window.onresize 事件创建一个处理程序。

JavaScript

 
window.onresize = this._resized.bind(this);
 
 

PageControlNavigator的构造函数代码中,onresize 事件最终会映射到在与当前 HTML 页面相关联的 JavaScript 文件中实现的updateLayout 函数。在运行时,onresize 事件调用此函数,此函数会将视图状态转发给页面。

updateLayout 的实现特定于每个页面。此代码显示了“拆分”模板的 items.js 中的updateLayout_initializeLayout 实现。(项页面是支持用户从ListView 中选择组的主页。用户选择组时,应用导航到拆分视图页面,即主信息/详细信息视图。)

JavaScript

 
updateLayout: function (element, viewState, lastViewState) {
     /// <param name="element" domElement="true" />
     var listView = element.querySelector(".itemslist").winControl;
     if (lastViewState !== viewState) {
          if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
               var handler = function (e) {
               listView.removeEventListener("contentanimating", handler, false);
               e.preventDefault();
          }
          listView.addEventListener("contentanimating", handler, false);
          var firstVisible = listView.indexOfFirstVisible;
          this._initializeLayout(listView, viewState);
          if (firstVisible >= 0 && listView.itemDataSource.list.length > 0) {
                listView.indexOfFirstVisible = firstVisible;
           }
       }
   }
},
 
_initializeLayout: function (listView, viewState) {
 
    if (viewState === appViewState.snapped) {
        listView.layout = new ui.ListLayout();
    } else {
        listView.layout = new ui.GridLayout();
    }
},
 
 

updateLayout 中的第一行代码使用querySelector 方法获取ListView 控件:

JavaScript

 
var listView = element.querySelector(".itemslist").winControl;
 

updateLayout 中的其余代码会检查视图状态,设置动画(未显示),然后调用_initializeLayout_initializeLayout 会设置ListView 中项的水平或垂直排列。如果当前视图为辅屏视图,则项将垂直排列。否则,项将在网格视图中排列。

JavaScript

 
if (viewState === appViewState.snapped) {
    listView.layout = new ui.ListLayout();
} else {
    listView.layout = new ui.GridLayout();
}
 
 

这些代码示例中显示的模式由“拆分”模板和“网格”模板使用。“拆分”模板还支持与视图状态相关的特有行为。默认情况下,“拆分”模板中的拆分视图页面 (split.html) 是一个两列视图 — 主信息/详细信息视图。“拆分”模板还定义了一个称为单列视图的备用视图,适用于视图状态为贴靠或纵向时的情况。定义和处理此视图状态的代码包含在split.js 中。_isSingleColumn 函数定义单列视图状态:

JavaScript

 
_isSingleColumn:  function () {
    var viewState = Windows.UI.ViewManagement.ApplicationView.value;
    return (viewState === appViewState.snapped || viewState === appViewState.fullScreenPortrait);
},
 
 

_updateVisibility 函数是 split.js 中调用 _isSingleColumn 的众多函数之一。_updateVisibility 函数根据当前视图状态和选定项启用和禁用列的可见性。加载页面时,此函数在 split.js中由ready 函数调用,在视图状态发生更改时还由updateLayout 调用。首先,该函数会删除主列(如果之前定义了主列,即,如果应用已处于单列视图)。

JavaScript

 
_updateVisibility: function () {
    var oldPrimary = document.querySelector(".primarycolumn");
    if (oldPrimary) {
        utils.removeClass(oldPrimary, "primarycolumn");
    }
    if (this._isSingleColumn()) {
        if (this._itemSelectionIndex >= 0) {
            utils.addClass(document.querySelector(".articlesection"), "primarycolumn");
            document.querySelector(".articlesection").focus();
        } else {
            utils.addClass(document.querySelector(".itemlistsection"), "primarycolumn");
            document.querySelector(".itemlist").focus();
        }
    } else {
        document.querySelector(".itemlist").focus();
    }
}
 
 

如果应用处于单列视图,_updateVisibility 会指定一个新的主列,添加与选定项对应的列类型。如果选定了某个项,updateVisibility 会添加项详细信息部分(HTML 中的articlesection),如下所示。

JavaScript

 
utils.addClass(document.querySelector(".articlesection"), "primarycolumn");
 

如果未选定任何项,updateVisibility 则会添加项列表部分(HTML 中的itemlistsection),如此处所示。

JavaScript

 
utils.addClass(document.querySelector(".itemlistsection"), "primarycolumn");
 

split.js 中的多个函数可基于视图状态修改“后退”按钮历史记录或导航行为。ready 函数和updateLayout 函数可修改“后退”按钮历史记录。selectionChanged 函数(当选定列表视图中某个项时被调用)可修改导航行为。

 

 


原创粉丝点击