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的名字
至此,也完成了数组的绑定

 

 

 

 


 


 

 

 

 

 

 

 

 

 

 


 


 

 

 

 

 


 

 

 

 

由于提供的参考引用内容与该问题不相关,无法依据参考引用回答此问题。以下是关于如何将 ControlWindow 的 API 重构为使用固定手动按钮绑定而非动态点的一般性思路: ### 定义绑定结构体和模式 首先,需要定义一个结构体来表示按钮绑定。这个结构体应包含按钮的标识、对应的操作以及可能的状态信息。 ```c // 定义按钮绑定结构体 typedef struct { int button_id; // 按钮的唯一标识 void (*action)(void); // 按钮按下时执行的操作 int state; // 按钮的状态 } ButtonBinding; // 定义绑定模式 typedef enum { MODE_NORMAL, MODE_ALTERNATE } BindingMode; ``` ### 移除旧的手动点代码 从 `ControlWindow` 和 `modbusclient` 中找到并移除所有与旧的手动点相关的代码。这可能包括动态点的定义、初始化、更新和处理逻辑。 ### 替换为新的绑定设置、状态更新和按钮交互处理 以下是一个简单的示例,展示如何设置绑定、更新状态和处理按钮交互: ```c #include <stdio.h> // 定义按钮绑定结构体 typedef struct { int button_id; // 按钮的唯一标识 void (*action)(void); // 按钮按下时执行的操作 int state; // 按钮的状态 } ButtonBinding; // 定义绑定模式 typedef enum { MODE_NORMAL, MODE_ALTERNATE } BindingMode; // 示例操作函数 void button_action_1() { printf("Button 1 pressed!\n"); } void button_action_2() { printf("Button 2 pressed!\n"); } // 初始化按钮绑定 void setup_bindings(ButtonBinding bindings[], int num_bindings) { bindings[0].button_id = 1; bindings[0].action = button_action_1; bindings[0].state = 0; bindings[1].button_id = 2; bindings[1].action = button_action_2; bindings[1].state = 0; } // 处理按钮按下事件 void handle_button_press(ButtonBinding bindings[], int num_bindings, int button_id) { for (int i = 0; i < num_bindings; i++) { if (bindings[i].button_id == button_id) { bindings[i].action(); bindings[i].state = 1; // 更新按钮状态 break; } } } // 处理按钮释放事件 void handle_button_release(ButtonBinding bindings[], int num_bindings, int button_id) { for (int i = 0; i < num_bindings; i++) { if (bindings[i].button_id == button_id) { bindings[i].state = 0; // 更新按钮状态 break; } } } int main() { ButtonBinding bindings[2]; setup_bindings(bindings, 2); // 模拟按钮按下 handle_button_press(bindings, 2, 1); // 模拟按钮释放 handle_button_release(bindings, 2, 1); return 0; } ``` ### 相关问题 1. 如何处理绑定模式的切换? 2. 如何在多线程环境下安全地更新按钮状态? 3. 怎样添加更多的按钮操作类型? 4. 如何将按钮绑定信息保存到文件并在程序启动时加载? 5. 如何处理按钮绑定的错误情况,例如无效的按钮 ID?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值