cocos2dx-js 多层级列表(改进)

6 篇文章 0 订阅
4 篇文章 0 订阅
博客介绍了如何在cocos2dx-js中改进多层级列表,使得列表能适应不同客户端的数据格式。通过添加一个变量指向子列表,并在关键函数中进行相应替换,允许开发者自定义子列表字段,如`shoes`。同时,增加了 `_itemParent` 字段来记录父节点数据,方便在回调中获取父项信息。
摘要由CSDN通过智能技术生成

上一篇文章http://blog.csdn.net/afei198409/article/details/51327163中说到"渲染多级时,子列表数据必须放在sub_items数组中,如 {txt:"item 1", sub_items:[{txt:"sub item 1"},...]}",这就限制了数据的格式,实际上使用时会感觉很不方便,因为每个客户端的数据格式都不一致.
如开发者A是为某一鞋店开发客户端的,它的数据格式可能是这样的:
//鞋子列表
[
{id:0, name:"品牌1", shoes:[{id:10001, name:"男装休闲鞋", price:30}, {id:10002, name:"女装休闲鞋", price:30}, ...]},
{id:1, name:"品牌2", shoes:[{id:20001, name:"男装运动鞋", price:60}, {id:20002, name:"女装运动鞋", price:60}, ...]},
......
]
如上所见,shoes实际上就是一个子列表,如果要使用上文的多层级列表则就要重新构造数据,将它变成以下格式:
//新的鞋子列表
[
{id:0, name:"品牌1", sub_items:[{id:10001, name:"男装休闲鞋", price:30}, {id:10002, name:"女装休闲鞋", price:30}, ...]},
{id:1, name:"品牌2", sub_items:[{id:20001, name:"男装运动鞋", price:60}, {id:20002, name:"女装运动鞋", price:60}, ...]},
......
]
这的确令人尴尬.
下面主要针对这个问题作改进:
var CommonList = cc.Node.extend({
...
sub_items : "sub_items", //  1.添加一个变量,该变量是一个string,用于指向子列表
...
enableSubItem : function(tag, item_field) { // 2.在启用多层级的同时也修改子列表的指向
        this.enable_sub_item = tag;
        if(typeof (item_field) == 'string') {
            this.sub_items = item_field;
        }
    },
...

// 3.在所有访问子列表数据的地方进行相应的替换,如下:dataSet[i].sub_items替换成dataSet[i][this.sub_items]
getItemData : function(dataSet) {
        if(!dataSet || dataSet.length === 0) {
            return;
        }
        for(var i = 0, len = dataSet.length; i < len; ++i) {
            this._itemData.push(dataSet[i]);
            if(this.enable_sub_item && dataSet[i]._itemOpen && dataSet[i][this.sub_items]) { // <--这里
                this.getItemData(dataSet[i][this.sub_items]); // <--这里
            }
        }
    },
...
resetData : function(dataSet, itemType, itemParent) {
        if(!dataSet || dataSet.length === 0) {
            return;
        }
        for(var i = 0, len = dataSet.length; i < len; ++i) {
            dataSet[i]._itemLevel = itemType;       //层级(从0开始计算)
            dataSet[i]._itemOpen = false;           //展开标记
            dataSet[i]._itemIndex = i;              //当前层级下的索引(从0开始计算)
            dataSet[i]._itemCnt = dataSet.length;   //当前层级总计算
            dataSet[i]._itemParent = itemParent;    //当前层级父节点
            if(this.enable_sub_item && dataSet[i][this.sub_items]) { // <--这里
                this.resetData(dataSet[i][this.sub_items], itemType + 1, dataSet[i]); // <--这里
            }
        }
    },
...
closeItem: function (data) {
        data._itemOpen = false;
        if(data[this.sub_items] && 0 < data[this.sub_items].length) { // <--这里
            for(var ind = 0; ind < data[this.sub_items].length; ++ind) { // <--这里
                this.closeItem(data[this.sub_items][ind]); // <--这里
            }
        }
    },
...
tableCellTouched:function (table, cell) {
        ...
        if(this.enable_sub_item) {
            if(data[this.sub_items] && 0 < data[this.sub_items].length) { // <--这里
                data._itemOpen = data._itemOpen ? false : true;
                reload = true;
                //收缩其所有子项
                if(!data._itemOpen) {
                    this.closeItem(data);
                }
            }else {
                data._itemOpen = false;
            }
        }
...
    },
...
});
现在我们重新使用CommonList来对鞋店列表进行渲染:
var common_list = new CommonList(l_size);
common_list.addItemPrefab(res.UIItemPrefab_1, 551, 60);
common_list.addItemPrefab(res.UIItemPrefab_2, 551, 63);
var list_delegate = {};
list_delegate.setItem = function (node, data) {
...
};
list_delegate.onItemClick = function (node, data) {
...
};
common_list.setDelegate(list_delegate);


var list_dataSet = [
{id:0, name:"品牌1", shoes:[{id:10001, name:"男装休闲鞋", price:30}, {id:10002, name:"女装休闲鞋", price:30}, ...]},
{id:1, name:"品牌2", shoes:[{id:20001, name:"男装运动鞋", price:60}, {id:20002, name:"女装运动鞋", price:60}, ...]},
......
];
common_list.enableSubItem(true, "shoes"); //启用多层级并修改子列表数据指向,让它指向shoes
common_list.reloadData(list_dataSet);
至此,数据结构限制就解除了.


不知你有没有注意到,上面改进时也另添加了另一项数据改进:
resetData : function(dataSet, itemType, itemParent) {
...
for(var i = 0, len = dataSet.length; i < len; ++i) {
...
dataSet[i]._itemParent = itemParent;    //当前层级父节点
...
}
},
_itemParent记录父节点数据.它有何用处呢?
如当点击列表"男装休闲鞋"这一项时,会触发回调:
list_delegate.onItemClick = function (node, data) {
...
};
这时这里参数data指向{id:10001, name:"男装休闲鞋", price:30},这个时候如果开发者想得到这一子项的父节点数据,如id,name,直接访问data._itemParent即可得到:
data._itemParent.id //值为 0
data._itemParent.name //值为 "品牌1"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值