数据绑定是在应用程序 UI 与数据源创建链接的过程。若是绑定正确数据,则当数据更改其值时,绑定到数据的UI属性值会自动反映更改。DeviceOne支持灵活的数据绑定,使UI展现和数据能够清晰的分离。目前还不支持双向绑定,只支持数据到展现的传递。
使用DeviceOne开发App,你能够不使用任何数据bind机制,传统的获取对象,给对象每个单个属性设置值也能够实现全部功能。可是使用bind机制能够减小代码,优化框架,使开发工做事半功倍。node
bind包括源和目标,DeviceOne的bind目标一般指UI组件,全部的UI组件都支持基本的bind方式。实际上只要一个组件有属性就能够支持bind,好比UI和MM(MultitonModule)组件都有属性,都支持bind。web
bind的源咱们目前提供了2个组件do_ListData
和do_HashData
分别表示二种数据结构,hash和array,由于整个DeviceOne的数据基础都是json格式,因此这2个数据组件都是只能处理json格式。json
UI和MM类的基类都提供了3个相关的方法来实现bind机制。数组
setMapping
方法:设置一个UI组件或者MM组件的属性和数据的映射关系。bindData
方法:设置UI组件或者MM组件的数据源,这个数据源目前只能是do_ListData
和do_HashData
.refreshData
方法:当bind的数据源数据发生变化后,调用这个方法来刷新数据源的展现。1 function test1() { 2 // 建立一个HashData对象 3 var data = mm("do_HashData"); 4 // 给Button建立一个属性到数据的映射,其中text和bgColor是Button的2个属性 5 btn1.setMapping({ 6 "text" : "text_key", 7 "bgColor" : "color_key" 8 }); 9 // 创建Button和HashData的绑定 10 btn1.bindData(data); 11 // 数据变化驱动UI属性变化 12 // 1. 修改数据 13 data.addData({ 14 "text_key" : "映射到HashData", 15 "color_key" : "FF0022AA" 16 }); 17 // 2. 刷新UI,这个按钮的文本变成“映射到HashData”,背景颜色变为“FF0022AA" 18 btn1.refreshData(); 19 }
其中一个UI的映射能够做为bindData的一个参数,好比数据结构
1 function test2() { 2 // 建立一个HashData对象 3 var data = mm("do_HashData"); 4 // 创建Button和HashData的绑定,同时设置映射关系 5 btn2.bindData(data, { 6 "text" : "text_key", 7 "bgColor" : "color_key" 8 }); 9 // 数据变化驱动UI属性变化 10 // 1. 修改数据 11 data.addData({ 12 "text_key" : "映射到HashData-直接设置映射", 13 "color_key" : "FFCC00AA" 14 }); 15 // 2. 刷新UI,这个按钮的文本变成“映射到HashData-直接设置映射”,背景颜色变为“FFCC00AA" 16 btn2.refreshData(); 17 } 18 // ...
其中HashData对象支持path,中间用.号来隔开,好比app
function test3() { // 建立一个HashData对象 var data = mm("do_HashData"); // 给Button建立一个属性到数据的映射,其中text和bgColor是Button的2个属性 // HashData对象支持path,中间用.号来隔开 btn3.setMapping({ "text" : "node1.text_key", "bgColor" : "node1.color_key" }); // 创建Button和HashData的绑定 btn3.bindData(data); // 数据变化驱动UI属性变化 // 1. 修改数据 data.addData({ "node1" : { "text_key" : "映射到HashData-支持path", "color_key" : "F00FEEAA" }, "node2" : "xxxx" }); // 2. 刷新UI,这个按钮的文本变成“映射到HashData-支持path”,背景颜色变为“F00FEEAA" btn3.refreshData(); }
其中数据源也支持ListData,中间用:加数字索引来代表是一个list的一个元素框架
function test4() { // 建立一个HashData对象 var data = mm("do_HashData"); // 给Button建立一个属性到数据的映射,其中text和bgColor是Button的2个属性 // HashData对象支持json array,中间用:加数字索引来代表是一个array的一个元素 btn4.setMapping({ "text" : "node1:2.text_key", "bgColor" : "node1:2.color_key" }); // 创建Button和HashData的绑定 btn4.bindData(data); // 数据变化驱动UI属性变化 // 1. 修改数据 data.addData({ "node1" : [ { "text_key" : "我是Button1", "color_key" : "FFFFEEAA" }, { "text_key" : "我是Button2", "color_key" : "FFFFEEBB" }, { "text_key" : "映射到HashData-支持JSONArray", "color_key" : "00FFEECC" } ], "node2" : "xxxx" }); // 2. 刷新UI,这个按钮的文本变成“映射到HashData-支持JSONArray”,背景颜色变为“00FFEECC" btn4.refreshData(); } function test5() { // 建立一个ListData对象 var data = mm("do_ListData"); // 给Button建立一个属性到数据的映射,其中text和bgColor是Button的2个属性 // do_ListData对象支持:加数字索引来代表是一个array的一个元素 btn5.setMapping({ "text" : ":2.text_key", "bgColor" : ":2.color_key" }); // 创建Button和HashData的绑定 btn5.bindData(data); // 数据变化驱动UI属性变化 // 1. 修改数据 data.addData([ { "text_key" : "我是Button1", "color_key" : "FFFFEEAA" }, { "text_key" : "我是Button2", "color_key" : "FFFFEEBB" }, { "text_key" : "映射到ListData", "color_key" : "0FF11ECC" } ]); // 2. 刷新UI,这个按钮的文本变成“映射到HashData-支持JSONArray”,背景颜色变为“00F11ECC" btn5.refreshData(); }
其中bind目标UI也支持path,中间用.隔开,只不过有一个限制就是这个时候的绑定目标UI必须是这个ui文件的根节点。这种状况应用更灵活方便,不须要为每个UI建立一个映射和一个数据源,这个ui文件里全部UI组件能够共用一个映射和数据源。好比ide
function test6() { // 根据统配符$来获取ui文件的根节点,也能够根据它的ID获取对象 var rootview = ui("$"); // 建立一个HashData对象 var data = mm("do_HashData"); // 给rootview建立多个子UI的属性到数据的映射,其中button_id1.text和label_id1.text // 分别表示这个ui文件里一个id为button_id1的Button组件和id为label_id1的Label组件 rootview.setMapping({ "do_Button_6.text" : "node1.text_key", "do_Button_7.text" : "node2", "do_Button_6.bgColor" : "node1.color_key", "do_Button_7.bgColor" : "node3" }); // 创建Button和HashData的绑定 rootview.bindData(data); // 数据变化驱动UI属性变化 // 1. 修改数据 data.addData({ "node1" : { "text_key" : "多个子UI绑定1", "color_key" : "1FFFE1BB" }, "node2" : "多个子UI绑定2", "node3" : "1111FFBB" }); // 2. 刷新UI,二个按钮的文本变成“多个子UI绑定1,2”,背景颜色变为“1F1F1EBB,11111EBB" rootview.refreshData(); }
这种bind机制不是全部UI组件都具备的,只有相似ListView,GridView等组件才有,这种组件的共性在于用户看到的视图是有限的,可是实际上经过手势滑动能够有不少个数量不定的视图。这种bind有如下几个概念:优化
templates
:模板是这种类型组件的一个属性,里面包含的是ui文件名。无论这种View有多少个子视图,可是模板数量是固定的,好比大部分ListView有不少个单元,可是这些单元都是共用一个或几个模板,只不过每个单元对应的数据不同。bindItems
:这个是这种类型组件的一个方法,这个方法的参数只能是do_ListData
,代表这个视图和一个list数据结构的数组对象绑定在一块儿。refreshItems
:相似UI基类的refreshData方法,这个方法是这种类型组件的一个方法。当bind的ListData发生变化后,经过这个方法来刷新界面。如下是一个ListView的示例代码,这里面的代码其实是写在不一样的2个ui文件对应的ui.js文件里,好比ListView所在的文件叫listview_sample.ui.js
ui
// listview_sample.ui.js文件 // 创建绑定..... // 1. 根据ListView的ID获取一个ListView的对象 var listview = ui("listview_id1"); // 2. 设置ListView的模板,这里只设置了一个模板文件,其实有可能有多个。 //这个示例中,假设这个模板文件里面只有一个id为button_id1的Button组件 //在ui文件里设置listview的templates属性为"source://listview_cell.ui" //也可能支持多模板好比templates属性为"source://listview_cell1.ui,source://listview_cell2.ui" // 3. 建立一个ListData对象 var data = mm("do_ListData"); // 4. 创建ListView和ListData的绑定 listview.bindItems(data); // 数据变化驱动UI属性变化 // 1. 修改数据 data.addData([{"text_key":"我是Button1","color_key":"#FFFFEEAA"}, {"text_key":"我是Button2","color_key":"#FFFFEEBB"}, {"text_key":"我是Button3","color_key":"#FFFFEECC"}, {"text_key":"我是Button4","color_key":"#FFFFEEDD"}, {"text_key":"我是Button5","color_key":"#FFFFEEEE"}, ]); // 2. 刷新UI,这个ListView会增长6个子视图,每一个视图里的按钮的文本变成“我是Button”+n, //背景颜色变为“FFFFEE"+XX listview.refreshItems();
以上的例子想要运行成功,还须要在listview_cell.ui对应的listview_cell.ui.js
文件里添加如下相似代码
1 //listview_cell.ui.js文件 2 // 创建绑定..... 3 // 1. 根据统配符$来获取ui文件的根节点,也能够根据它的ID获取对象 4 var rootview = ui($); 5 // 2. 给rootview建立子UI的属性到数据的映射,其中button_id1.text和button_id1.bgColor 6 //表示这个ui文件里有一个id为button_id1的Button组件 7 rootview.setMapping({"button_id1.text":"text_key","button_id1.bgColor":"color_key"}); 8 //注意这里不须要再单独bind一个数据源了,这个文件做为listview的模板文件,会自动和listview绑定的数据创建bind关系。 9 //listview绑定的数组数据中每一项元素都是这个模板文件的数据源。
ListView用的很广,示例也很是多,参考示例大全
这个事件也很重要,一般一个UI对象和一个Hashdata创建映射关系以后,当hashdata更新数据后,UI对象调用refreshData或refreshItems后,UI对象会接受到数据,而后更新对应的属性值,以后会触发这个事件。
这个事件会一般能够用在Listview,Gridview,Slideview这种UI组件,它们都包含多个ui文件,都有模板ui文件。经过这个事件能够实现主ui和模板ui的数据通信。
详细的示例咱们参考数据传递的文档