如何使用模板绑定数据 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

Windows JavaScript 库模板为格式化并显示多个数据实例的便捷方式。可以将这些模板与 ListViewFlipView 对象结合使用来指定希望它们显示的方式。也可以使用模板绑定数据对象的多个实例,而不是使用预定义的视图。 有关将模板与 ListView 一起使用的详细信息,请参阅快速入门:添加 ListView。有关将模板与 FlipView 一起使用的详细信息,请参阅添加 FlipView 控件。以下过程显示如何将模板与数组一起使用。

可将模板以声明方式定义为 WinJS 控件并指定其内部结构和样式。即便声明它们作为 DIV 元素,模板也不会作为 DOM 的一部分进程处理,并且不会作为 DOM 搜索结果的一部分返回。可以指定 DIV 元素(模板应在其中出现),或者允许 render 方法创建它自己的 DIV 元素。 本主题介绍如何使用模板将可变数量的可绑定数据对象绑定到 DIV 元素中。用户通过从下拉列表中选择项来选择要显示的对象数。

先决条件

说明

步骤 1: 设置项目以使用模板

若要设置项目以使用模板,请完成以下步骤。

Hh700356.wedge(zh-cn,WIN.10).gif

  1. 使用 JavaScript 创建一个空白 Windows 应用商店应用并将其命名为 TemplateExample

  2. 在 default.html 文件的 BODY 元素内,为模板添加 DIV 元素且提供 ID templateDiv,然后添加具有值为 "WinJS.Binding.Template"data-win-control 属性,如此处所示。

    <body>
        <div id="templateDiv" data-win-control="WinJS.Binding.Template"></div> 
    </body>
    

    在定义数据对象后将返回以添加模板的内部结构。

步骤 2: 定义数据对象并将其绑定到模板的字段中

  1. 在 default.js 中立即调用的函数内,声明一个包含了若干字段的对象。在这种情况下,我们将使用 WinJS.Binding.define,从而可使所有属性都可绑定。

    
    (function () {
        "use strict";
    
        // Other app code ...
    
        // Define a Person object with bindable properties.
        var Person = WinJS.Binding.define({
            name: "",
            color: "",
            birthday: "",
            petname: "",
            dessert: ""
        });
    
    })();
    
  2. 若要在模板中显示此对象的字段,你将需要一个其项与数据对象的字段对应的列表,如此处所示。在 default.html 中,将以下代码添加到 BODY 标记内。

    <div id="templateDiv" data-win-control="WinJS.Binding.Template">
        <div class="templateItem" data-win-bind="style.background: color">
            <ol>
                <li><span>Name :</span><span data-win-bind="textContent: name"></span></li>
                <li><span>Birthday:</span><span data-win-bind="textContent: birthday"></span></li>
                <li><span>Pet's name: </span><span data-win-bind="textContent: petname"></span></li>
                <li><span>Dessert: </span><span data-win-bind="textContent: dessert"></span></li>
            </ol>
        </div>
    </div>
    
  3. 在 default.html 中的模板代码下,添加应该在其中呈现模板的 DIV 元素。

    <div id="templateControlRenderTarget"></div>
    

步骤 3: 控制显示对象的数量

鉴于此示例的目的,我们将实例化三个 Person 对象并添加下拉列表,以便用户可以选择要显示的 Person 对象数。

  1. 在 default.html 中的 BODY 标记内,添加以下代码。

    <fieldset id="templateControlObject">
        <legend>Pick a name:</legend>
        <select id="templateControlObjectSelector">
            <option value="0">Show one</option>
            <option value="1">Show two</option>
            <option value="2">Show three</option>
        </select>
    </fieldset>
    
  2. 在 default.js 中立即调用的匿名函数内,创建三个 Person 对象的数组。

    
    (function () {
        "use strict";
    
        // Other app code ...
    
        // Define a Person 'class' with bindable properties.
        var Person = WinJS.Binding.define({
            name: "",
            color: "",
            birthday: "",
            petname: "",
            dessert: ""
        });
    
        // Declare an array of People objects.
        var people = [
            new Person({name:"Bob", color:"red", birthday:"2/2/2002", petname:"Spot", dessert:"chocolate cake"}),
            new Person({name:"Sally", color:"green", birthday:"3/3/2003", petname:"Xena", dessert:"cherry pie"}),
            new Person({name:"Fred", color:"blue", birthday:"2/2/2002", petname:"Pablo", dessert:"ice cream"}),
        ];
    
    })();
    
  3. 3. 现在向下拉选择器的更改事件中添加侦听器。将此代码添加到 default.js 中 app.onactivated 事件的处理程序内。

    app.onactivated = function (args) {
    
        // Other activation code ...
    
        var selector = document.querySelector("#templateControlObjectSelector");
              selector.addEventListener("change", handleChange, false); 
    
    }
    

在更改事件处理程序中,选择包含模板和指定数据显示位置的 DIV 元素,然后在模板控件(你可以从“templateDiv”元素的 wincontrol 属性获取该控件)上调用 render。 在模板上调用 render 时,数据对象的相关字段绑定到模板的列表项。

function handleChange(evt) {
    var templateElement = document.querySelector("#templateDiv");
    var renderElement = document.querySelector("#templateControlRenderTarget");
    renderElement.innerHTML = "";

    var selected = evt.target.selectedIndex;
    var templateControl = templateElement.winControl;

    while (selected >= 0) {
        templateElement.winControl.render(people[selected--], renderElement); 
    } 
}

现在你可以构建和调试应用了。在下拉列表中进行选择时,应用会显示相应数量的数据对象。

步骤 4: 允许呈现以添加一个 DIV

你不必为 render 函数提供一个你已创建的 DIV;如果未指定 DIV,则 render 会创建一个新 DIV。但是,你必须将新 DIV 添加到 DOM。请注意 render 的返回值是 WinJS.Promise。(有关承诺的详细信息,请参阅快速入门:使用承诺)。在承诺的 done 方法中,你添加了一个添加新 DIV 的函数。

更改上一步的 while 块,如下所示。


    while (selected >= 0) {
        templateElement.winControl.render(people[selected--])
            .done(function (result) {
                 renderElement.appendChild(result);
            });        
    }

备注

下面是本主题中代码的完整列表。

default.html (Windows)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>TemplateExample</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <!-- TemplateExample references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <div id="templateDiv" data-win-control="WinJS.Binding.Template">
        <div class="templateItem" data-win-bind="style.background: color">
            <ol>
                <li>Name: <span data-win-bind="textContent: name"></span></li>
                <li>Birthday: <span data-win-bind="textContent: birthday"></span></li>
                <li>Pet's name: <span data-win-bind="textContent: petname"></span></li>
                <li>Dessert: <span data-win-bind="textContent: dessert"></span></li>
            </ol>
        </div>
    </div>
    <div id="templateControlRenderTarget"></div>
    <fieldset id="templateControlObject">
        <legend>Pick a name:</legend>
        <select id="templateControlObjectSelector">
            <option value="0">Show one</option>
            <option value="1">Show two</option>
            <option value="2">Show three</option>
        </select>
    </fieldset>
</body>
</html>

default.html (Windows Phone)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>TemplateBinding</title>

    <!-- WinJS references -->
    <link href="/css/ui-themed.css" rel="stylesheet" />
    <script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
    <script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>

    <!-- TemplateBinding references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <div id="templateDiv" data-win-control="WinJS.Binding.Template">
        <div class="templateItem" data-win-bind="style.background: color">
            <ol>
                <li>Name: <span data-win-bind="textContent: name"></span></li>
                <li>Birthday: <span data-win-bind="textContent: birthday"></span></li>
                <li>Pet's name: <span data-win-bind="textContent: petname"></span></li>
                <li>Dessert: <span data-win-bind="textContent: dessert"></span></li>
            </ol>
        </div>
    </div>
    <div id="templateControlRenderTarget"></div>
    <fieldset id="templateControlObject">
        <legend>Pick a name:</legend>
        <select id="templateControlObjectSelector">
            <option value="0">Show one</option>
            <option value="1">Show two</option>
            <option value="2">Show three</option>
        </select>
    </fieldset>
</body>
</html>

default.js(Windows 和 Windows Phone)


(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {

            } else {

            }
       
            // Add event handler to selector. 
            var selector = document.querySelector("#templateControlObjectSelector");
            selector.addEventListener("change", handleChange, false);

            args.setPromise(WinJS.UI.processAll());

        }
    };

    app.start();

    // Define a Person 'class' with bindable properties.
    var Person = WinJS.Binding.define({
        name: "",
        color: "",
        birthday: "",
        petname: "",
        dessert: ""
    });

    // Declare an array of People objects.
    var people = [
        new Person({ name: "Bob", color: "red", birthday: "2/2/2002", petname: "Spot", dessert: "chocolate cake" }),
        new Person({ name: "Sally", color: "green", birthday: "3/3/2003", petname: "Xena", dessert: "cherry pie" }),
        new Person({ name: "Fred", color: "blue", birthday: "2/2/2002", petname: "Pablo", dessert: "ice cream" }),
    ];

    // Update the displayed data when the selector changes.
    function handleChange(evt) {
        var templateElement = document.querySelector("#templateDiv");
        var renderElement = document.querySelector("#templateControlRenderTarget");
        renderElement.innerHTML = "";

        var selected = evt.target.selectedIndex;
        var templateControl = templateElement.winControl;

        while (selected >= 0) {
            templateElement.winControl.render(people[selected--])
                .done(function (result) {
                    renderElement.appendChild(result);
                });        
        }
    }
})();

相关主题

快速入门:添加 ListView

添加 FlipView 控件