win8_绑定复杂对象

http://msdn.microsoft.com/zh-cn/library/windows/apps/hh700355.aspx在许多情况下,你希望你的应用绑定到复杂的对象,特别是管理不由应用的 UI 控制的处理的那些对象。 本主题介绍如何编写应用(该应用显示包含某个名称和某种颜色的某个对象中的数据),这基本上与快速入门:绑定数据和样式相同。在这种情形下,对象管理更改进程自身,而不是响应触发更改的按钮。

 

先决条件

说明

步骤 1: 设置项目以使用绑定

  1. 创建使用 JavaScript 为 Windows 构建的空白 Windows 应用商店应用并将其命名为 ObjectBinding

  2. 添加用于绑定的 DIV 元素并为其提供 ID“objectBinding”,嵌入式文本 Welcome 以及具有 ID“bindableSpan”的 SPAN 元素,如此处所示。

    
    <body>
        <div id="objectBinding">
          Welcome
          <span id="bindableSpan"></span>
        </div>
    </body>
    
    

步骤 2: 设置复杂对象

  1. 定义具有名称和颜色字段的 Person 对象,名称数组、颜色名称数组以及为数组提供随机索引的专用方法。对于此对象的定义,可以使用 WinJS.Class.define 方法。

    
    <script type="text/javascript">
        var Person = WinJS.Class.define(
            function() {
                this.name = "Harry";
                this.color = "blue";
                this.timeout = null;
            }, {
    
            _nameArray:
                new Array("Sally", "Jack", "Hal", "Heather", "Fred", "Paula", "Rick", "Megan", "Ann", "Sam"),
            _colorArray:
                new Array("lime", "lavender", "yellow", "orange", "pink", "greenyellow", "white", "lightblue", "lightgreen", "lightyellow"),
    
            _newName: function () {
                this.name = this._nameArray[this._randomizeValue()];
                this.color = this._colorArray[this._randomizeValue()];
            },
            _randomizeValue: function () {
                var value = Math.floor((Math.random() * 1000) % 8);
                if (value < 0)
                    value = 0;
                else if (value > 9)
                    value = 9;
                return value;
            }
        });
    </script>
    
    
  2. 现在将两种公共方法添加到 Person 定义,这两种方法用于启动和停止每 500 毫秒更改名称和颜色字段的进程。

    
    start: function () {
        var that = this;
        if (this.timeout === null) {
            this.timeout = setInterval(function () { that._newName(); }, 500);
        }
    }, 
    
     stop: function () {
        if (this.timeout !== null) {
        clearInterval(this.timeout);
            this.timeout = null;
        }
    }
    
    

步骤 3: 将对象绑定到 HTML

  1. Person 对象不能立即看到结果;也就是说,该对象未在更改时提供通知。可以通过将 Person 对象与正确的绑定功能结合来观察该对象。WinJS.Class.mix 函数将 WinJS.Binding.mixin 对象的功能添加到 Person 对象中,前一对象包括 bind 方法和 WinJS.Binding.expandProperties 函数的功能,从而准备将对象字段用于绑定。在 Person 对象定义之后调用 WinJS.Class.mix(你需要先定义 Person 类,然后才可以将任何对象与其混合)。

    
    WinJS.Class.mix(Person,
        WinJS.Binding.mixin,
        WinJS.Binding.expandProperties({name: "", color: ""})
    ); 
    
    
  2. 还需要在 Person 构造函数内调用 _initObservable 以设置 _backingData 属性。按照如下方式更改 Person 构造函数:

    
    ...
    function () {
        this._initObservable();
    
        this.name = "Harry";
        this.color = "blue";
        this.timeout = null;
        }
    ...
    
    
    
  3. 在已实例化某个 Person 对象之后,你可以将其绑定到两个属性。bind 方法带有两个参数:要绑定的属性或字段的名称,以及指定如何绑定函数的函数。此函数有两个参数:新值和旧值。由于bind 为实例方法,因此目前我们只是在其名称和颜色字段上实例化 Person 并调用 bind。在调用WinJS.Class.mix 之后立即添加以下代码。

    
    var myPerson = new Person();
    
    myPerson.bind("name", onNameChange);
    
    myPerson.bind("color", onColorChange);
    
    function onNameChange (newValue) {
        var span = document.getElementByIdx_x("bindableSpan");
        span.innerText = newValue;
    }
    
    function onColorChange (newValue) {
        var span = document.getElementByIdx_x("bindableSpan");
        span.style.color = newValue;
    }
    
    

    警告  不要试图将数据绑定到 HTML 元素的 ID。

  4. 若要使更改事件发生,则必须更改 _newname 函数,以便该函数使用 setProperty 方法。

    
    _newName: function () {
        this.setProperty("name", this._nameArray[this._randomizeValue()]);
        this.setProperty("color", this._colorArray[this._randomizeValue()]);
        }
    
    
  5. 可以通过调用 start 方法来测试绑定。

    
    myPerson.start();
    
    

    构建并运行应用时,应看到以下内容:

    Welcome, Harry(欢迎你,哈里)

    名称和名称颜色应不断更改。

步骤 4: 将绑定对象作为激活过程的一部分添加

现在,我们将获取对 Person 对象的生存时间的更多控制,方法是在激活处理程序中实例化并绑定该对象,在卸载处理程序中解除绑定并破坏该对象。

  • 将激活和卸载事件处理程序作为 WinJS.Utilities.ready 函数的一部分添加。此函数在DOMContentLoaded 事件之后被立即调用,而该事件在解析页面之后,但在加载所有资源之前触发。

    
    var myPerson = new Person();
    
    WinJS.Utilities.ready(function () {
        WinJS.Application.addEventListener("activated", activatedHandler);
        WinJS.Application.addEventListener("unload", unloadHandler);
      }, false);
    
    function activatedHandler(e) {
        myPerson.bind("name", onNameChange);
        myPerson.bind("color", onColorChange);
        myPerson.start();
    }
    
    function onNameChange (newValue) {
        var span = document.getElementByIdx_x("bindableSpan");
        span.innerText = newValue;
    }
    
    function onColorChange (newValue) {
        var span = document.getElementByIdx_x("bindableSpan");
        span.style.color = newValue;
    }
    
    function unloadHandler(e) {
        myPerson.stop();
        myPerson.timeout = null;
        myPerson.unbind("name", onNameChange);
        myPerson.unbind("color", onColorChange);
        myPerson = null;
    }
    
    

完整示例

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


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

    <!-- WinJS references -->
    <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>

    <!-- ObjectBinding references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <div id="objectBinding">
        Welcome
        <span id="bindableSpan"></span>
    </div>
    <script type="text/javascript">
        var Person = WinJS.Class.define(
            function () {
                this._initObservable();
                this.name = "Harry";
                this.color = "blue";
                this.timeout = null;
            }, {

                _nameArray:
                    new Array("Sally", "Jack", "Hal", "Heather", "Fred", "Paula", "Rick", "Megan", "Ann", "Sam"),
                _colorArray:
                    new Array("lime", "lavender", "yellow", "orange", "pink", "greenyellow", "white", "lightblue", "lightgreen", "lightyellow"),

                _newName: function () {
                    this.setProperty("name", this._nameArray[this._randomizeValue()]);
                    this.setProperty("color", this._colorArray[this._randomizeValue()]);
                },
                
                _randomizeValue: function () {
                    var value = Math.floor((Math.random() * 1000) % 8);
                    if (value < 0)
                        value = 0;
                    else if (value > 9)
                        value = 9;
                    return value;
                },

                start: function () {
                    var that = this;
                    if (this.timeout === null) {
                        this.timeout = setInterval(function () { that._newName(); }, 500);
                    }
                },

                stop: function () {
                    if (this.timeout !== null) {
                        clearInterval(this.timeout);
                        this.timeout = null;
                    }
                }
            });

        WinJS.Class.mix(Person,
            WinJS.Binding.mixin,
            WinJS.Binding.expandProperties({ name: "", color: "" })
        );

        var myPerson = new Person();

        WinJS.Utilities.ready(function () {
            WinJS.Application.addEventListener("activated", activatedHandler);
            WinJS.Application.addEventListener("unload", unloadHandler);
        }, false);

        function activatedHandler(e) {
            myPerson.bind("name", onNameChange);
            myPerson.bind("color", onColorChange);
            myPerson.start();
        }

        function onNameChange (newValue) {
            var span = document.getElementByIdx_x("bindableSpan");
            span.innerText = newValue;
        }

        function onColorChange (newValue) {
            var span = document.getElementByIdx_x("bindableSpan");
            span.style.color = newValue;
        }

        function unloadHandler(e) {
            myPerson.stop();
            myPerson.timeout = null;
            myPerson.unbind("name", onNameChange);
            myPerson.unbind("color", onColorChange);
            myPerson = null;
        }
</script>
</body>
</html>


//////////////////////////////////////default.js//////////////////////////////////

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    WinJS.Binding.optimizeBindingReferences = true;

    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) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    app.start();
})();
///////////////////////////////////////////////default.html////////////////////
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>ObjectBinding</title>

    <!-- WinJS references -->
    <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>

    <!-- ObjectBinding references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <div id="objectBinding">
        Welcome
        <span id="bindableSpan"></span>
    </div>
    <script type="text/javascript">
        var Person = WinJS.Class.define(
            function () {
                this._initObservable();
                this.name = "Harry";
                this.color = "blue";
                this.timeout = null;
            }, {

                _nameArray:
                    new Array("Sally", "Jack", "Hal", "Heather", "Fred", "Paula", "Rick", "Megan", "Ann", "Sam"),
                _colorArray:
                    new Array("lime", "lavender", "yellow", "orange", "pink", "greenyellow", "white", "lightblue", "lightgreen", "lightyellow"),

                _newName: function () {
                    this.setProperty("name", this._nameArray[this._randomizeValue()]);
                    this.setProperty("color", this._colorArray[this._randomizeValue()]);
                },

                _randomizeValue: function () {
                    var value = Math.floor((Math.random() * 1000) % 8);
                    if (value < 0)
                        value = 0;
                    else if (value > 9)
                        value = 9;
                    return value;
                },

                start: function () {
                    var that = this;
                    if (this.timeout === null) {
                        this.timeout = setInterval(function () { that._newName(); }, 500);
                    }
                },

                stop: function () {
                    if (this.timeout !== null) {
                        clearInterval(this.timeout);
                        this.timeout = null;
                    }
                }
            });

        WinJS.Class.mix(Person,
            WinJS.Binding.mixin,
            WinJS.Binding.expandProperties({ name: "", color: "" })
        );

        var myPerson = new Person();

        WinJS.Utilities.ready(function () {
            WinJS.Application.addEventListener("activated", activatedHandler);
            WinJS.Application.addEventListener("unload", unloadHandler);
        }, false);

        function activatedHandler(e) {
            myPerson.bind("name", onNameChange);
            myPerson.bind("color", onColorChange);
            myPerson.start();
        }

        function onNameChange(newValue) {
            var span = document.getElementByIdx_x("bindableSpan");
            span.innerText = newValue;
        }

        function onColorChange(newValue) {
            var span = document.getElementByIdx_x("bindableSpan");
            span.style.color = newValue;
        }

        function unloadHandler(e) {
            myPerson.stop();
            myPerson.timeout = null;
            myPerson.unbind("name", onNameChange);
            myPerson.unbind("color", onColorChange);
            myPerson = null;
        }
</script>
</body>
</html>
//////////////////////////////////////////////////////////////////////////
发布了76 篇原创文章 · 获赞 4 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章