所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

AdvancedDataGrid选中行全部数据获取方法|详细代码示例与实现步骤

AdvancedDataGrid选中行全部数据获取方法|详细代码示例与实现步骤 一

文章目录CloseOpen

从基础到进阶:获取选中行数据的完整路径

基础方法:3行代码搞定常规场景

其实Adobe官方给的API里,最直接的方法就是用selectedItems属性,我敢说80%的基础场景用这个就够了。你可能会说“我试过啊,有时候拿不到数据”,那多半是没搞清楚它的使用条件。我举个最简单的例子,如果你用ArrayCollection作为数据源,单选状态下直接grid.selectedItems就能拿到选中的那一行数据,返回的是一个Array,里面每个元素就是选中行的完整对象。比如你绑定的数据源是orderAC(ArrayCollection类型),里面每个对象有idproductNameprice字段,那获取选中行的价格就可以这么写:

var selectedRows:Array = advDataGrid.selectedItems;

if(selectedRows.length > 0){

var firstRow:Object = selectedRows[0];

trace("选中行价格:" + firstRow.price);

}

这里有个细节要注意,selectedItems返回的是Array类型,就算是单选,它也是只有一个元素的数组,所以千万别直接selectedItems.price,我见过好几个新手栽在这。另外如果你用的是XMLList数据源,稍微有点不同,这时候selectedItems里的元素是XML对象,获取字段需要用@属性名,比如firstRow.@productName,这点要特别留意,不然会拿到空值。

去年我帮同事小王改代码时,他就遇到个怪事:多选状态下selectedItems返回的数组长度总是对的,但里面的数据有重复。后来发现他在dataProvider更新后没有重置选中状态,导致旧数据和新数据混在一起了。所以你在数据源变化时,最好手动清空选中状态,比如advDataGrid.selectedItems = [],亲测这个小习惯能避免很多莫名其妙的问题。

进阶技巧:处理复杂场景的3个实用方案

如果你的项目里有更复杂的需求,比如要区分单选/多选模式、需要实时监听选中变化,或者数据源是嵌套结构,那基础方法可能不够用了。我 了三个实战中常用的进阶方案,你可以根据情况选。

第一个是“状态监听+数据过滤”组合拳。有时候你不仅要获取选中行,还要在用户选中时立即处理数据,这时候可以监听change事件。我之前做一个库存管理系统时,需要用户选完商品后立即计算总价,当时就是用这个方法:

advDataGrid.addEventListener(ListEvent.CHANGE, onSelectionChange);

private function onSelectionChange(event:ListEvent):void{

var selectedData:Array = advDataGrid.selectedItems;

var totalPrice:Number = 0;

for each(var item:Object in selectedData){

totalPrice += Number(item.price) * Number(item.quantity);

}

// 更新总价显示

}

这里要注意,change事件在单选和多选时都会触发,但如果用户快速连续点击,可能会触发多次,所以可以加个节流处理,比如用setTimeout延迟50毫秒执行,避免性能问题。

第二个是处理嵌套数据结构。比如你的dataProvider是包含子对象的,像{id:1, product:{name:"手机", price:5000}, quantity:2},这时候直接拿item.price肯定不行。我通常会写一个工具函数,递归获取需要的字段,比如:

function getNestedValue(item:Object, path:String):Object{

var parts:Array = path.split(".");

var value:Object = item;

for each(var part:String in parts){

if(value.hasOwnProperty(part)){

value = value[part];

}else{

return null;

}

}

return value;

}

// 使用时:getNestedValue(selectedItem, "product.price")

这个方法我在好几个项目里都用过,不管数据嵌套多深,只要传对路径就能拿到值,比每次手动拆解方便多了。

第三个是性能优化,如果你处理的是上万行数据的表格,直接用selectedItems可能会有点卡。这时候可以用selectedIndices先拿到索引,再从数据源里取数据,尤其是dataProvider是ArrayCollection时,getItemAt(index)的效率比遍历selectedItems高不少。Adobe的Flex官方文档里也提到过,当数据量超过1000行时,优先使用索引操作(,nofollow),亲测在大数据量下能把响应速度提升2-3倍。

避坑指南:实战中常见问题与解决方案

问题1:选中状态判断失误导致数据错乱

你可能遇到过这种情况:明明在界面上选中了某行,代码里selectedItems却为空,或者返回的是上一次选中的数据。这多半是因为你忽略了selected属性和selectedItems的同步问题。我之前排查过一个项目,发现他们在代码里手动修改了dataProvider后,没有刷新选中状态,导致selectedItems里还是旧数据。正确的做法是,在数据源更新后,调用advDataGrid.invalidateList()刷新列表,同时重置选中状态,就像这样:

// 更新数据源后

advDataGrid.dataProvider = new ArrayCollection(newData);

advDataGrid.invalidateList(); // 刷新列表

advDataGrid.selectedItems = []; // 清空选中状态

还有一种情况是单选模式下用了selectedItem(单数)而不是selectedItems(复数),虽然selectedItem能直接拿到单个对象,但如果你的表格允许多选(selectionMode="multipleRows"),这时候selectedItem只会返回第一个选中的行,导致数据丢失。所以我 不管单选多选,统一用selectedItems,然后根据长度判断是单选还是多选,这样更稳妥。

问题2:数据字段不匹配引发的“隐形bug”

这个问题太常见了,尤其是多人协作的项目。比如后端返回的字段是product_price,但前端代码里写的是price,这时候selectedItems虽然能拿到对象,但item.price就是undefined。我之前带实习生时,他就踩过这个坑,查了一下午才发现是字段名大小写不一致——后端返回的是Price,他写的是price

为了避免这种问题,我养成了一个习惯:在获取数据前先做字段映射检查。可以写个简单的校验函数,比如:

function checkFields(item:Object, requiredFields:Array):Boolean{

for each(var field:String in requiredFields){

if(item[field] === undefined){

trace("缺少必要字段:" + field);

return false;

}

}

return true;

}

然后在获取选中行后调用:checkFields(selectedItem, ["id", "price", "quantity"]),这样能在开发阶段就暴露问题,比上线后用户反馈再排查效率高多了。如果是大型项目,还可以用TypeScript(如果是Flex项目可以用ASDoc注解)定义数据接口,强制字段类型和名称匹配,不过这就是进阶操作了。

问题3:大数据量下的性能优化

如果你的表格有几千上万行数据,直接遍历selectedItems可能会卡顿,尤其是在移动端或低配置设备上。我之前做一个物流管理系统,表格有5000多行订单数据,用户多选100行后,页面直接卡了3秒。后来我用了两个优化技巧,把时间压缩到了200毫秒以内。

第一个是“按需获取”,只提取需要的字段,而不是整个对象。比如你只需要idprice,就别把整个item都存起来,这样能减少内存占用:

var simplifiedData:Array = [];

for each(var item:Object in advDataGrid.selectedItems){

simplifiedData.push({

id: item.id,

price: item.price

});

}

第二个是使用Vector代替Array存储数据。Vector是强类型数组,遍历速度比普通Array快30%-50%(Adobe官方性能测试数据)。如果你的数据类型固定,比如都是Object,可以这样用:

var selectedVect:Vector. = new Vector.();

for each(var item:Object in advDataGrid.selectedItems){

selectedVect.push(item);

}

如果多选行数特别多(比如超过500行), 用setTimeout分批次处理数据,避免UI线程阻塞。比如每处理100行,休息10毫秒,这样用户就不会觉得页面卡住了。

最后想跟你说,获取选中行数据看似简单,但细节里藏着很多“坑”。我上面说的这些方法,都是我和身边同事在项目里踩过坑后 出来的,你可以直接拿去用。记得在实际开发中多测试几种场景——单选、多选、数据源更新、快速操作,这样才能确保代码稳定。如果你按这些方法试了,遇到问题可以留言,我会尽量帮你分析!


你有没有遇到过这种情况?明明在表格里改了选中行的数据——比如把订单价格从5000改成了5500,结果点”确定”的时候,用代码一拿selectedItems,还是显示5000?我之前帮财务系统改bug时就碰到过,用户改了单价,保存时却按旧价格提交了,查了半天才发现问题出在数据更新和选中状态没同步上。其实这不是组件的锅,主要是我们忽略了一个关键点:AdvancedDataGrid的selectedItems存的是对数据源对象的引用,但如果数据源更新后表格没刷新,或者选中状态没重新绑定,它就只会拿着最初选中时的”快照”,自然拿不到最新数据。

解决这个问题其实就两步,但很多人容易漏掉第二步。第一步你肯定知道,改完数据后得让表格刷新显示吧?这时候就得用invalidateList()方法,它会告诉表格”数据源变了,重新画一遍”,不然你改了数据,表格上可能都看不到变化,更别说拿新数据了。不过光刷新还不够,我之前就踩过坑——刷新后表格显示是新价格了,但selectedItems里还是旧的。这是因为选中状态还绑着原来的引用,得让表格重新”认识”一下选中的行。所以第二步,如果需要保留用户的选中状态,就得用selectedIndices绕个弯:先把当前选中的索引记下来(比如var indices = grid.selectedIndices),然后清空选中(grid.selectedIndices = []),再把索引塞回去(grid.selectedIndices = indices)。这么一折腾,表格就会重新从数据源里读最新的数据,这时候再拿selectedItems,保证是热乎乎的新数据。我在那个财务系统里加了这两步后,用户改价格保存的bug再也没出现过,亲测好用。


为什么用selectedItems获取选中行数据时返回空值?

这种情况通常有三个常见原因:一是数据源类型不匹配,比如使用XMLList作为数据源时,需通过“@属性名”获取字段(如item.@price),而非直接item.price;二是未检查selectedItems的长度,单选时它也是包含一个元素的数组,需通过selectedItems[0]访问;三是数据源更新后未重置选中状态,导致旧数据残留, 在dataProvider变化后执行advDataGrid.selectedItems = []清空选中。

单选和多选模式下,获取选中行数据的方法有区别吗?

基础方法一致,都是通过selectedItems属性获取,但处理方式略有不同。单选时selectedItems返回长度为1的数组,可直接取第一个元素(selectedItems[0]);多选时返回包含所有选中行的数组,需遍历处理。需注意:即使设置了单选模式(selectionMode=”singleRow”),selectedItems仍为数组类型,不要直接用selectedItems.字段名访问,这是新手常犯的错误。

使用XMLList作为数据源时,如何正确获取选中行的字段值?

XMLList数据源与ArrayCollection不同,选中行数据是XML对象,需通过“@属性名”获取字段值。例如数据源为,获取价格时需写成selectedRow.@price,而非selectedRow.price。如果直接用点语法,会因XML对象的属性访问规则不同导致返回空值,这点在处理XMLList时要特别注意。

表格数据量很大(如上万行),获取选中行数据时卡顿,怎么优化?

大数据量下可从两方面优化:一是改用selectedIndices获取索引,再通过dataProvider.getItemAt(index)取数据,避免直接遍历selectedItems(尤其ArrayCollection数据源,getItemAt效率更高);二是“按需提取”字段,只保留需要的字段(如只存id和price),减少内存占用;三是分批次处理,多选大量行时用setTimeout每处理100行暂停10毫秒,避免阻塞UI线程,亲测可提升2-3倍响应速度。

选中行数据更新后,如何确保获取到最新数据?

需确保选中状态与数据源同步。当dataProvider中的数据更新(如修改某行price)后,若未重新选中该行,直接获取selectedItems可能还是旧值。 更新数据后执行两步操作:一是调用advDataGrid.invalidateList()刷新表格显示;二是如果需要保留选中状态,用selectedIndices重新选中(如var indices:Array = advDataGrid.selectedIndices; advDataGrid.selectedIndices = []; advDataGrid.selectedIndices = indices),强制表格重新读取数据源最新数据。

原文链接:https://www.mayiym.com/45254.html,转载请注明出处。
0
显示验证码
没有账号?注册  忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码