數據綁定介紹

數據綁定是在應用程序 UI 與數據源創建鏈接的過程。若是綁定正確數據,則當數據更改其值時,綁定到數據的UI屬性值會自動反映更改。DeviceOne支持靈活的數據綁定,使UI展現和數據能夠清晰的分離。目前還不支持雙向綁定,只支持數據到展現的傳遞。
使用DeviceOne開發App,你能夠不使用任何數據bind機制,傳統的獲取對象,給對象每個單個屬性設置值也能夠實現全部功能。可是使用bind機制能夠減小代碼,優化框架,使開發工做事半功倍。node

1.基本綁定方式:

bind包括源和目標,DeviceOne的bind目標一般指UI組件,全部的UI組件都支持基本的bind方式。實際上只要一個組件有屬性就能夠支持bind,好比UI和MM(MultitonModule)組件都有屬性,都支持bind。web

bind的源咱們目前提供了2個組件do_ListDatado_HashData分別表示二種數據結構,hash和array,由於整個DeviceOne的數據基礎都是json格式,因此這2個數據組件都是隻能處理json格式。json

UI和MM類的基類都提供了3個相關的方法來實現bind機制。數組

  • setMapping方法:設置一個UI組件或者MM組件的屬性和數據的映射關係。
  • bindData方法:設置UI組件或者MM組件的數據源,這個數據源目前只能是do_ListDatado_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();
}

2. 特殊綁定方式:

這種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.jsui

// 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用的很廣,示例也很是多,參考示例大全

3. dataRefreshed 事件:

這個事件也很重要,一般一個UI對象和一個Hashdata創建映射關係以後,當hashdata更新數據後,UI對象調用refreshData或refreshItems後,UI對象會接受到數據,而後更新對應的屬性值,以後會觸發這個事件。
這個事件會一般能夠用在Listview,Gridview,Slideview這種UI組件,它們都包含多個ui文件,都有模板ui文件。經過這個事件能夠實現主ui和模板ui的數據通信。
詳細的示例咱們參考數據傳遞的文檔

相關文章
相關標籤/搜索