data and bindings

WinJS爲我們提供了一些數據綁定的方法來實現MVC和MVVC這種架構,使我們對應用數據的管理和更新變得更加方便

首先,需要創建一個viewmodel,新建一個js文件,並在文件中添加如下代碼:

///<reference path="//Microsoft.WinJS.1.0/js/base.js"/>
///<reference path="//Microsoft.WinJS.1.0/js/ui.js"/>

(function () {

    "use strict"

    WinJS.Namespace.define("ViewModel.UserData", {

        
            _shoppingItems:[],
            _preferredStores:[],

            homeZipCode: null,
        
            getStore: function () {
                return this._preferredStore;
            },

            addStore: function (newStore) {
                this._preferredStore.push(newStore);
            },

            getItems: function () {
                return this._shoppingItems;
            },

            addItems: function (newName, newQuanity, newStore) {
                this._shoppingItems.push({
                    item: newName,
                    quanity: newQuanity,
                    store:newStore
                });
            }
    });

    ViewModel.UserData.homeZipCode = "NY 10086";

    ViewModel.UserData.addStore("Yuki");
    ViewModel.UserData.addStore ("Nike");

    ViewModel.UserData.addItems("Kobe8", 1, "Nike");


})();

這樣就定義了一個全局變量,在整個工程裏都可以使用,在html文件中添加viewmodel.js的路徑:

<script src="viewmodel.js的url"></script>

第一種bindings叫做基本聲明綁定,即只能綁定簡單變量,類和數組等不能通過這種方法綁定

在html文件中添加一個span,用來顯示綁定的內容:

        The Zip Code is <span id="zipCode" class="TheZipCode" data-win-bind="innerText:UserData.homeZipCode"></span>

homeZipCode爲viewmodel.js文件中所定義的ViewModel.UserData裏的一個簡單變量

然後再default.js文件的app.onactivated函數裏添加如下代碼:

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

performInitialSetup(e)函數的實現如下:

WinJS.Binding.processAll(document.body, ViewModel);

這樣就完成了基本聲明綁定,可能大家會有疑問,爲什麼span的data-win-bind=“UserData.homeZipCode”而不是ViewModel.UserData.homeZipCode,這是因爲Declarative data bindings are relative to the data source

可是這種綁定只能顯示數據,並不能實現同步更新修改,這時,動態綁定可以幫我們實現

這裏需要用到一個函數WinJS.Binding.as(),把ViewModel的成員作爲一個object作爲WinJS.Binding.as函數的參數,對viewmodel.js文件作以下修改:

WinJS.Namespace.define("ViewModel", {

        UserData:WinJS.Binding.as({

            _shoppingItems:[],
            _preferredStores:[],

            homeZipCode: null,
        
            getStore: function () {
                return this._preferredStore;
            },

            addStore: function (newStore) {
                this._preferredStore.push(newStore);
            },

            getItems: function () {
                return this._shoppingItems;
            },

            addItems: function (newName, newQuanity, newStore) {
                this._shoppingItems.push({
                    item: newName,
                    quanity: newQuanity,
                    store:newStore
                });
            }

        }),
    });

在html文件裏添加一個輸入文本框和一個更新按鈕:

.Enter a new zip code:<input id="zipCodeInput" data-win-bind="value:UserData.homeZipCode" />
        <button id="update">update</button>

接着,在之前的performInitialSetup(e)函數裏添加代碼,是在點擊更新按鈕之後,以輸入文本框裏的內容重置homeZipCode的值:

WinJS.Utilities.query('#update').listen("click", function (e) {
            ViewModel.UserData.homeZipCode = WinJS.Utilities.query('#zipCodeInput')[0].value;
        });

這樣在輸入一些東西之後,點擊更新,就可以看到之前綁定的span的內容也更新爲輸入的東西

完成了簡單變量的綁定,接下來便是一些複雜變量的綁定了,如數組

這時,需要WinJS.Binding.List(),UserData中的兩個數組不再是私有成員,必須將其定義爲全局變量,在viewmodel.js裏做如下修改:

var shoppingItems =new WinJS.Binding.List();
    var preferredStore =new WinJS.Binding.List();

    WinJS.Namespace.define("ViewModel", {

        UserData:WinJS.Binding.as({


            homeZipCode: null,
        
            getStore: function () {
                return preferredStore;
            },

            addStore: function (newStore) {
                preferredStore.push(newStore);
            },

            getItems: function () {
                return shoppingItems;
            },

            addItems: function (newName, newQuanity, newStore) {
                shoppingItems.push({
                    item: newName,
                    quanity: newQuanity,
                    store:newStore
                });
            }

        }),
   });

在html中添加additem按鈕和removeitem按鈕還有一個顯示最後添加的Item的newName的span:

the last item is:<span id="item"></span>
        <button id="additem">Add Item</button>
        <button id="removeitem">Remove Item</button>

在performIntialSetup(e)函數裏如入下如下代碼:

WinJS.Utilities.query('button').listen("click", function (e) {
            if (this.id == "additem") {
                console.log("additem succeed");
                ViewModel.UserData.addItems("Kobe9", 1, "Nike");
            }
            else
                if(this.id=="removeitem")
                {
                    ViewModel.UserData.getItems().pop();
                }
        });

        var setValue = function () {
            var list = ViewModel.UserData.getItems();
            document.getElementById('item').innerText = list.getAt(list.length - 1).item;
        };

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

        setValue();

eventType的設置是相當重要的,這樣,當有新item插入,它纔會響應並更新最後插入的item的名字
至此,也完成了數組的綁定

 

 

 

 


 


 

 

 

 

 

 

 

 

 

 


 


 

 

 

 

 


 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章