WinJS 库是由 CSS 和 JavaScript 文件组成的。使用Visual Studio 2012新建一个JavaScript 的Windows应用商店的空白应用程序项目,在项目的引用管理器中会默认添加这个库,如图19-1所示:
图19-1 JavaScript 的 WinJS库
上图可以看出,WinJS库主要包含ui-dark.css、ui-light.css、base.js和ui.js四个文件。其中ui-dark.css和ui-light.css是JavaScript主题风格库,ui-dark.css表示昏暗风格,而ui-light.css表示明亮风格;base.js是WinJS的基础类库,包含了处理程序激活、挂起、异常等行为的函数;ui.js是WinJS控件库,包含了一些Windows 应用商店应用的前台界面常用的控件和控件样式。
新建项目的default.html页面会默认引用WinJS 库中的ui-dark.css、base.js 和ui.js文件。相关代码如下所示:
<!-- WinJS 库的引用 -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
2.
WinJS库中的命名空间
为了防止同名函数和变量发生冲突,同时也可以方便代码的管理,在WinJS库中也使用了命名空间的概念来规划库中的资源,这些命名空间封装了与Windows应用商店应用开发相关的对象和函数。通过相应的命名空间名称能对该空间里的对象和函数进行访问。接下来介绍WinJS库中几个主要的命名空间。
(1)WinJS.UI.Pages命名空间
WinJS.UI.Pages命名空间主要包含PageControl 控件和 define函数。其中PageControl 控件与其他的WinJS库控件有所不同,它是一种自定义控件,需要使用WinJS.UI.Pages命名空间下的define函数来定义PageControl控件。define函数有两个参数,一个是uri,另一个是members,uri为页面的地址,members是对这个页面中的成员进行的一些初始化操作,相关语法格式代码如下所示:
var pageControl = WinJS.UI.Pages.define(uri, members);
(2)WinJS.Binding 命名空间
WinJS.Binding 命名空间里面主要包含在数据与模板绑定时所使用的一些对象,如List对象和Template对象。List对象用于表示数据列表,通过WinJS.Binding.List函数可以新建一个List对象,该函数有一个数组类型的参数,表示初始化列表的数据集合,语法格式代码如下所示:
var JSlist = new WinJS.Binding.List(list);
例如先定义一个数据集合myData,然后使用WinJS.Binding.List函数创建一个itemsList数据列表,并用myData数据集合初始化该数据列表,相关代码如下所示:
//数据集合
var myData = [
{ title: "Banana", text: "Low-fat frozen yogurt", picture: "images/Banana.png" },
{ title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/Lemon.png" },
{ title: "Marvelous Mint", text: "Gelato", picture: "images/Mint.png" },
{ title: "Creamy Orange", text: "Sorbet", picture: "images/Orange.png" },
{ title: "Succulent Strawberry", text: "Sorbet", picture: "images/Strawberry.png" }
];
// 创建一个List对象
var itemsList = new WinJS.Binding.List(myData);
在上面的代码中,首先定义用于初始化列表的数据集合myData,myData是一个数组类型的对象,包含了五个数据对象,每个数据对象都有三个属性title、text和picture,其中title属性的值为数据对象的标题,text属性的值为对数据对象的描述,picture属性的值为数据对象中图片的地址。接着以myData为参数调用WinJS.Binding.List函数创建一个itemsList数据列表。
Template对象即Template控件,用于格式化显示数据内容。值得注意的是Template控件内部只能有一个根元素,向Template控件添加其他元素都要在这个根元素里添加。向页面中添加Template控件可以通过在body元素中定义一个div元素,并将div元素的data-win-control属性设置为"WinJS.Binding.Template"来完成。
下面演示向页面中添加一个Template控件,并在Template控件里添加用于显示图片的img元素和用于显示标题的h4元素,相应代码如下所示:
<body>
<div id="templatebinding" data-win-control="WinJS.Binding.Template">
<div>
<img src="images/Banana.png"/>
<h4>
Banana</h4>
</div>
</div>
</body>
在上面代码中,首先在页面的body元素里面定义一个div元素,并将div元素的data-win-control属性设置为"WinJS.Binding.Template"来向页面中添加Template控件。接下来向Template控件添加img和h4两个元素,由于Template控件内部只能有一个根元素,因此先为Template控件添加一个div元素作为根元素。然后向根元素添加img元素和h4元素,并设置img元素的src属性值为"images/Banana.png",h4元素的显示内容为"Banana"。
另外WinJS.Binding 命名空间内还有一个processAll函数,该函数用来查找绑定目标元素的data-win-bind属性,通过此方法可以把数据源与绑定目标关联在一起。后面在介绍简单对象的数据绑定时会用到processAll函数。processAll函数中有两个参数,一个是rootElement,另一个是dataContext。其中rootElement为绑定目标,dataContext为绑定源,语法格式代码如下所示:
WinJS.Binding.processAll(rootElement, dataContext);
(3)WinJS.UI命名空间
WinJS.UI命名空间提供一些常用的控件和初始化操作函数,例如DatePicker控件、ListView控件和AppBar控件等常用控件以及processAll函数,这里的processAll函数与上面介绍的processAll函数功能不同。接下来简单介绍下WinJS.UI 命名空间里面的主要控件和函数。
DatePicker控件用于选择一个date类型的值,如用户可以选择年份、月份、日期等信息。通过定义一个div元素,并将data-win-control属性设置为"WinJS.UI.DatePicker"可以向页面中添加DatePicker控件。相关代码如下所示:
<div data-win-control="WinJS.UI.DatePicker"></div>
ListView控件用于以列表或者网格的形式显示多条数据。可以通过定义一个div元素,并将data-win-control属性设置为"WinJS.UI.ListView"来向页面中添加ListView控件,还可以通过div元素的data-win-options属性设置ListView控件的属性和值,相关代码如下所示:
<div data-win-control="WinJS.UI.ListView" data-win-options="{ property : value}"></div>
AppBar控件用于定义一个显示操作命令的应用栏。可以通过定义一个div元素,并将data-win-control属性设置为"WinJS.UI.AppBar"来向页面中添加AppBar控件,相关代码如下所示:
<div data-win-control="WinJS.UI.AppBar"></div>
AppBarCommand控件是在AppBar控件中显示的一条命令。一般通过定义一个button元素,并将button元素的data-win-control属性设置为"WinJS.UI.AppBarCommand"来向AppBar控件中添加AppBarCommand命令控件,还可以通过button元素的data-win-options属性设置AppBarCommand控件的属性和值,相关代码如下所示:
<div data-win-control="WinJS.UI.AppBar">
<button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{ property : value}" ></button>
</div>
Rating控件用于方便地进行评级。该控件有个averageRating属性,使用这个属性开发者可以获取或者设置平均评级。通过定义一个div元素,并将data-win-control属性设置为"WinJS.UI.Rating"来向页面中添加Rating控件,相关代码如下所示:
<div data-win-control="WinJS.UI.Rating"></div>
HtmlControl控件用于加载一个HTML页面。可以通过定义一个div元素,并将data-win-control属性设置为"WinJS.UI.HtmlControl"来向页面中添加HtmlControl控件,还可以使用div元素的data-win-options属性把HtmlControl控件的uri属性设置成所要加载的页面地址,相关代码如下所示:
<div data-win-control="WinJS.UI.HtmlControl" data-win-options="{uri: '/pages/HtmlControlPage.html'}" ></div>
processAll函数用于初始化页面中WinJS库控件。基于空白项目模板新建的应用程序项目中,default.js文件中默认调用了WinJS.UI.processAll 函数,相关代码如下所示:
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
// 此应用程序刚刚启动。在此处初始化应用程序。
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
}
//此应用程序已从挂起状态重新激活。在此处恢复应用程序状态。
else {
}
args.setPromise(WinJS.UI.processAll());
}
};
下面通过一个小示例演示如何使用Rating控件和WinJS.UI.processAll函数,首先在Visual Studio 2012中新建一个JavaScript 的Windows应用商店的空白应用程序项目,将其命名为rating。然后打开default.html文件,向body元素中添加Rating控件,相关代码如下所示:
<body>
<div id="ratingControlHost" data-win-control="WinJS.UI.Rating"></div>
</body>
布置好前台界面后,接下来打开default.js文件,为processAll函数添加初始化代码,相关代码如下所示:
args.setPromise(WinJS.UI.processAll().done(function () {
var control = document.getElementById("ratingControlHost").winControl;
control.averageRating = 3;
})
);
在上面代码中,首先在setPromise函数里调用WinJS.UI.processAll 函数来初始化所添加的Rating控件,通过getElementById函数获取id为"ratingControlHost"的Rating控件,然后把该控件的averageRating属性设置为3。
(4)WinJS.Class命名空间
WinJS.Class命名空间包含一个define函数,用于自定义类。这个函数中有三个参数,一个是constructor,一个是 instanceMembers,另一个是staticMembers。其中constructor参数是类的构造函数,instanceMembers参数为类的成员函数和成员属性,staticMembers参数为静态成员函数和成员属性,语法格式代码如下所示:
var object = WinJS.Class.define(constructor, instanceMembers, staticMembers);
例如使用define函数定义一个Person类,该类有name属性和一个静态属性harmsHumans,相关代码如下所示:
var Person = WinJS.Class.define(
function (name) {
this.name = name;
},
{ name: "" },
{ harmsHumans: false });
//声明并实例化Person对象
var person = new Person("paul");
person.name = "jack";
Person.harmsHumans = false;
上面代码中,首先定义Person类,接着实例化一个Person类的对象person,并设置该对象的name属性和harmsHumans属性。由于harmsHumans属性是一个静态属性,可以直接使用类名来调用。