Data && Binding

WinJS基于ECMAScript 5,具有面向对象属性。

在使用WinJS进行Windows 8 App开发时,为了数据与界面分开,可以使用MVVM设计模式。

mvvm由model、viewmodel、view组成,model中主要用来存储数据、viewmodel负责对数据的各种操作、view负责数据的呈现。

在WinJS开发中,使用mvvm时很合适的,因为就像做网页一样。

首先定义一个viewmodel.js

(function () {
    "use strict"

    var shoppingItemsList = new WinJS.Binding.List();
    var perferredStoresList = new WinJS.Binding.List();

    WinJS.Namespace.define("ViewModel", {

        UserData: WinJS.Binding.as({

            //public member
            homeZipCode: null,

            getStores: function () {
                return perferredStoresList;
            },
    
            addStore: function (newStore) {
                perferredStoresList.push(newStore);
            },

            getItems:  function() {
                return shoppingItemsList;
            },

            addItem: function (newName, newQuantity, newStore) {
                shoppingItemsList.push({
                    item: newName,
                    quantity: newQuantity,
                    store: newStore
                });
            }
        }),

        State: WinJS.Binding.as({
            selectedIndex: -1
        })
        
    });

    
    ViewModel.UserData.homeZipCode = "NY 10118";

    ViewModel.UserData.addStore("Whole Foods");
    ViewModel.UserData.addStore("Korognh");
    ViewModel.UserData.addStore("Costco");
    ViewModel.UserData.addStore("Walmart");

    ViewModel.UserData.addItem("Apples", 4, "Whole Foods");
    ViewModel.UserData.addItem("Hotdogs", 12, "Costco");
    ViewModel.UserData.addItem("soda", "4 pack", "Costco");
   
})();
在这个viewmodel中现在只需要看UserData这个对象就可以了,其他的后面再说。

上面在定义viewmodel时,使用了namesapce,在WinJS开发中,使用命名空间可以减少全局变量的数量,也可以增加程序的阅读性。

定义UserData对象时,使用了WinJS.binding.as()方法,这个方法是将参数的对象作为一个可监察对象返回,也就是监察者模式在WinJS上的一个实现。需要注意的是,这个方法必须用在对象上,不可以用在属性上,用在属性上返回的只是一个静态对象,不是监察的。

使用监察者模式的好处就是,放对象的属性与界面的标签绑定之后,数据改变时,标签的内容也会改变,但是这个只是实现了数据从model到界面的单向流动,而当界面改变的时候,需要对数据也进行更新,这个就需要自己使用响应了实现啦。

对象属性与界面标签的绑定,可以使用下面的代码实现

            <div class="win-type-x-large">
                The zip code is :
                <span data-win-bind="innerText: UserData.homeZipCode"></span>
            </div>

在html文件某个标签中使用data-win-bind属性,进行声明,然后在对应的js文件中,使用WinJS.Binding.processAll(document.body, ViewModel);方法进行真正的绑定。第一个参数是dom对象,第二个是要进行绑定的对象。后面还有两个参数,有兴趣的朋友可以自己查看文档。

说完怎么从数据到界面的监测,下面说怎么从界面到数据的更新。

首先是界面中有一个输入框,可以让用户输入新数据

            <div class="win-type-x-large">
                <label for="newZip">Enter new zip code :</label>
                <input id="newZip" data-win-bind="value: UserData.homeZipCode" />
                <button id="newZipButton">Update Zip Code</button>
            </div>
然后在对应的js文件中,使用下面的方法

        WinJS.Utilities.query('#newZipButton').listen("click", function (e) {
            ViewModel.UserData.homeZipCode = WinJS.Utilities.query('#newZip')[0].value;
            console.log("zipcode ViewModel.UserData.homeZipCode");
        });

对按钮添加了单击的响应操作,获取用户输入的内容,并更新数据。

WinJS.Utilities.query()方法是类似JQuery的实现。

最后说一个使用WinJS.binding.list()对象时候需要注意的点。

当我们的数据是数组这样的类型时,又需要使用这些数据对界面进行更新,那么使用WinJS.bingding.list对象是不错的选择。但是如果使用了这个list对象,那么在声明绑定的时候,就不可以使用像上面那种在标签中直接声明绑定到对象的某个属性,这样的声明式的绑定方法。

使用WinJS。Bingding.List 对象对界面进行更新时,需要在对应的js文件中使用代码对dom对象进行更新。

首先在html中声明下面几个标签

            <h1 class="win-type-xx-lager">Left Full Container</h1>
            <div class="win-type-x-large">
                The last Item is <span id="listInfo">soda</span>
            </div>
            <div class="win-type-x-large">
                <button id="addItemButton">Add Item</button>
                <button id="removeItemButton">Remove Item</button>
            </div>

然后在对应的js文件中

  WinJS.Utilities.query('button').listen("click", function (e) {
            if (this.id == "addItemButton") {
                ViewModel.UserData.addItem("Ice Cream", 1, "Walmart");
            } else {
                ViewModel.UserData.getItems().pop();
            }
        });

        var setValue = function () {
            var list = ViewModel.UserData.getItems();
            if (list.length > 0) {
                document.getElementById("listInfo").innerText = list.getAt(list.length - 1).item;
            }
        };

        var eventTypes = ["itemchanged", "iteminserted", "itemmoved", "itemremoved"];
        eventTypes.forEach(function (type) {
            ViewModel.UserData.getItems().addEventListener(type, setValue);
        });

上面的代码首先为两个按钮添加了响应。

然后对viewmodel中UserData中的数据,只要数据有变动,就调用setValue()方法,对相应 的dom元素进行更新。


差不多就是这些,mvvm模式、Data Binding的基本使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值