如何在 Flex AdvancedDataGrid 中排序 - 未调用回调

发布于 2024-07-06 02:48:00 字数 3120 浏览 9 评论 0原文

我有一个使用客户数据分组的 AdvancedDataGrid。 并非所有组都位于层次结构中的同一级别,并且组可以同时包含组和成员。 我们有一个排序回调,但除了最叶级别的组之外,它不会被调用。 请参阅下面的代码示例 - 展开所有组,然后单击“出生日期”上的排序列以按出生日期进行反向排序。 (奇怪的是,出于某种难以理解的原因,第一个升序排序有效。)

我们没有被要求提供与组成员处于同一级别的任何数据。

我该如何解决?

谢谢。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
     layout="vertical" 
     verticalAlign="middle" 
     backgroundColor="white" >
  <mx:Script>
    <![CDATA[
      import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
      import mx.collections.HierarchicalData;
      import mx.utils.ObjectUtil;

      private var arrData : Array = [
        { name: "User A", dob: "04/14/1980" },
        { name: "User B", dob: "01/02/1975" },
        { name: "Group A", children: [
          { name: "User E", dob: "09/13/1972" },
          { name: "User F", dob: "11/22/1993" }
          ]
        },
        { name: "Group B", children: [
          { name: "Group B1", children: [
            { name: "User I", dob: "01/23/1984" },
            { name: "User J", dob: "11/10/1948" }
            ]
          },
          { name: "User G", dob: "04/09/1989" },
          { name: "User H", dob: "06/20/1963" }
          ]
        },
        { name: "User C", dob: "12/30/1977" },
        { name: "User D", dob: "10/27/1968" }
      ];

      private function date_sortCompareFunc(itemA:Object, itemB:Object):int
      {
        if ( itemA.hasOwnProperty("dob") && itemB.hasOwnProperty("dob"))
        {
          var dateA:Date = new Date(Date.parse(itemA.dob));
          var dateB:Date = new Date(Date.parse(itemB.dob));
          return ObjectUtil.dateCompare(dateA, dateB);
        }
        else if ( itemA.hasOwnProperty("dob"))
        {
          return 1;
        }
        else if (itemB.hasOwnProperty("dob"))
        {
          return -1;
        }
        return ObjectUtil.stringCompare(itemA.name, itemB.name);
      }

      private function date_dataTipFunc(item:Object):String
      {
        if (item.hasOwnProperty("dob"))
        {
          return dateFormatter.format(item.dob);
        }
        return "";
      }

      private function label_dob(item:Object, col:AdvancedDataGridColumn):String
      {
        var dob:String="";
        if(item.hasOwnProperty("dob"))
        {
          dob=item.dob;
        }
        return dob;
      }
    ]]>
  </mx:Script>

  <mx:DateFormatter id="dateFormatter" formatString="MMMM D, YYYY" />

  <mx:AdvancedDataGrid id="adgTest" dataProvider="{new HierarchicalData(this.arrData)}" designViewDataType="tree" width="746" height="400">
    <mx:columns>
      <mx:AdvancedDataGridColumn headerText="Name"  dataField="name"/>
      <mx:AdvancedDataGridColumn dataField="dob" headerText="Date of birth" 
           labelFunction="label_dob" 
           sortCompareFunction="date_sortCompareFunc"
           showDataTips="true" 
           dataTipFunction="date_dataTipFunc" />

    </mx:columns>
  </mx:AdvancedDataGrid>
</mx:Application>

I have an AdvancedDataGrid that uses customer grouping of data. Not all of the groups will be at the same level in the hierarchy, and groups can contain both groups and members. We have a sort callback, but it's not being called except for groups at the leaf-most levels. See code below for an example -- expand all of the groups, then click the sort column on "date of birth" to get a reverse sort by date of birth. (Oddly, for some unfathomable reason, the first ascending sort works.)

We're not getting called for any of the data that's grouped at the same level as a group member.

How do I fix this?

Thanks.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
     layout="vertical" 
     verticalAlign="middle" 
     backgroundColor="white" >
  <mx:Script>
    <![CDATA[
      import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
      import mx.collections.HierarchicalData;
      import mx.utils.ObjectUtil;

      private var arrData : Array = [
        { name: "User A", dob: "04/14/1980" },
        { name: "User B", dob: "01/02/1975" },
        { name: "Group A", children: [
          { name: "User E", dob: "09/13/1972" },
          { name: "User F", dob: "11/22/1993" }
          ]
        },
        { name: "Group B", children: [
          { name: "Group B1", children: [
            { name: "User I", dob: "01/23/1984" },
            { name: "User J", dob: "11/10/1948" }
            ]
          },
          { name: "User G", dob: "04/09/1989" },
          { name: "User H", dob: "06/20/1963" }
          ]
        },
        { name: "User C", dob: "12/30/1977" },
        { name: "User D", dob: "10/27/1968" }
      ];

      private function date_sortCompareFunc(itemA:Object, itemB:Object):int
      {
        if ( itemA.hasOwnProperty("dob") && itemB.hasOwnProperty("dob"))
        {
          var dateA:Date = new Date(Date.parse(itemA.dob));
          var dateB:Date = new Date(Date.parse(itemB.dob));
          return ObjectUtil.dateCompare(dateA, dateB);
        }
        else if ( itemA.hasOwnProperty("dob"))
        {
          return 1;
        }
        else if (itemB.hasOwnProperty("dob"))
        {
          return -1;
        }
        return ObjectUtil.stringCompare(itemA.name, itemB.name);
      }

      private function date_dataTipFunc(item:Object):String
      {
        if (item.hasOwnProperty("dob"))
        {
          return dateFormatter.format(item.dob);
        }
        return "";
      }

      private function label_dob(item:Object, col:AdvancedDataGridColumn):String
      {
        var dob:String="";
        if(item.hasOwnProperty("dob"))
        {
          dob=item.dob;
        }
        return dob;
      }
    ]]>
  </mx:Script>

  <mx:DateFormatter id="dateFormatter" formatString="MMMM D, YYYY" />

  <mx:AdvancedDataGrid id="adgTest" dataProvider="{new HierarchicalData(this.arrData)}" designViewDataType="tree" width="746" height="400">
    <mx:columns>
      <mx:AdvancedDataGridColumn headerText="Name"  dataField="name"/>
      <mx:AdvancedDataGridColumn dataField="dob" headerText="Date of birth" 
           labelFunction="label_dob" 
           sortCompareFunction="date_sortCompareFunc"
           showDataTips="true" 
           dataTipFunction="date_dataTipFunc" />

    </mx:columns>
  </mx:AdvancedDataGrid>
</mx:Application>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

素衣风尘叹 2024-07-13 02:48:00

似乎第一行包含空数据或空字符串,并且高级数据网格设置为使用分组数据,则不会调用排序函数。

是的,这有点像黑客,但如果您可以放入不切实际的(例如 1770 年 1 月 1 日),您可以在数据库/文件读取/数据输入级别插入的恒定数据,然后使用列 labelFunction 来如果数据与该列匹配,则呈现为 null,它应该可以工作,或者至少会调用排序函数。

 public function dateCellLabel(item:Object, column:AdvancedDataGridColumn):String
    {
        var date:String = item[column.dataField];

        if (date=="1/1/1770") 
            return null; 
        else
            return  date;
    }

很抱歉这么晚才回答这个问题,但至少如果其他人试图找到答案,他们可能会看到这个。

It seems as if the first row contains null data or an empty string, and the advanceddatagrid is set to use grouped data, then the sort function doesn't get called.

it's a bit of a hack, yes, but if you can put in an unrealistic (say 1/1/1770), constant piece of data that you could insert at the database/file read/data input level then use the column labelFunction to render as null if the data matches that column, it should work, or at least the sort function will get called.

 public function dateCellLabel(item:Object, column:AdvancedDataGridColumn):String
    {
        var date:String = item[column.dataField];

        if (date=="1/1/1770") 
            return null; 
        else
            return  date;
    }

Sorry about answering this so late, but at least if somebody else tries to find the answer, they might see this.

浮世清欢 2024-07-13 02:48:00

这与SortCompareFunction的逻辑有关。

dob:"01/01/1970" 放入所有组节点,排序按预期进行,对吗?

This has something to do with the logic of the SortCompareFunction.

Put dob:"01/01/1970" for all the group nodes and the sort works as expected, is that correct?

北城半夏 2024-07-13 02:48:00

我不认为问题在于用 null 或空字符串值(这是完全有效的值)对分组数据进行排序; 这
文档明确指出 dataField 表示的属性必须是 dataProvider [item] 上的有效属性,即它必须存在、为 null 或其他。

虽然我给 RaySir 投票,但我不太同意这是一种黑客行为,而是你正在标准化你的数据,我认为这是一个非常好的表示层要做的事情。

这是一个重新设计的示例:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical" 
    verticalAlign="middle" 
    backgroundColor="white" >
    <mx:Script>
        <![CDATA[
            import mx.collections.HierarchicalData;
            import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
            import mx.utils.ObjectUtil;

            private var arrData : Array = [
                { name: "User A", dob: "04/14/1980" },
                { name: "User B", dob: "01/02/1975" },
                { name: "Group A", dob: null, children: [
                    { name: "User E", dob: "09/13/1972" },
                    { name: "User F", dob: "11/22/1993" }
                ]
                },
                { name: "Group B", dob: null, children: [
                    { name: "Group B1", dob: null, children: [
                        { name: "User I", dob: "01/23/1984" },
                        { name: "User J", dob: "11/10/1948" }
                    ]
                    },
                    { name: "User G", dob: "04/09/1989" },
                    { name: "User H", dob: "06/20/1963" }
                ]
                },
                { name: "User C", dob: "12/30/1977" },
                { name: "User D", dob: "10/27/1968" }
            ];

            private function dob_sort(itemA:Object, itemB:Object):int {
                var dateA:Date = itemA.dob ? new Date(itemA.dob) : null;
                var dateB:Date = itemB.dob ? new Date(itemB.dob) : null;
                return ObjectUtil.dateCompare(dateA, dateB);
            }

            private function dob_dataTip(item:Object):String {
                if (!item.hasOwnProperty('children') && item.hasOwnProperty("dob")) {
                    return dateFormatter.format(item.dob);
                }
                return null;
            }

            private function dob_label(item:Object, col:AdvancedDataGridColumn):String {
                if(!item.hasOwnProperty('children') && item.hasOwnProperty("dob")) {
                    return item.dob;
                }
                return null;
            }
        ]]>
    </mx:Script>

    <mx:DateFormatter id="dateFormatter" formatString="MMMM D, YYYY" />

    <mx:AdvancedDataGrid id="adgTest" dataProvider="{new HierarchicalData(arrData)}" designViewDataType="tree" width="746" height="400">
        <mx:columns>
            <mx:AdvancedDataGridColumn headerText="Name"  dataField="name"/>
            <mx:AdvancedDataGridColumn headerText="Date of birth" dataField="dob"
                labelFunction="dob_label" 
                dataTipFunction="dob_dataTip"
                sortCompareFunction="dob_sort"
                showDataTips="true" />

        </mx:columns>
    </mx:AdvancedDataGrid>
</mx:Application>

I don't think the problem is to do with sorting grouped data with null or empty string values (which are perfectly valid values); the
docs clearly state the property represented by dataField must be a valid property on the dataProvider [item] i.e. it must exist, null or otherwise.

While I give RaySir my vote, I don't quite agree that it's a hack, but rather you're normalizing your data, which I think is a perfectly fine presentation-layer thing to do.

Here's is a re-worked example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical" 
    verticalAlign="middle" 
    backgroundColor="white" >
    <mx:Script>
        <![CDATA[
            import mx.collections.HierarchicalData;
            import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
            import mx.utils.ObjectUtil;

            private var arrData : Array = [
                { name: "User A", dob: "04/14/1980" },
                { name: "User B", dob: "01/02/1975" },
                { name: "Group A", dob: null, children: [
                    { name: "User E", dob: "09/13/1972" },
                    { name: "User F", dob: "11/22/1993" }
                ]
                },
                { name: "Group B", dob: null, children: [
                    { name: "Group B1", dob: null, children: [
                        { name: "User I", dob: "01/23/1984" },
                        { name: "User J", dob: "11/10/1948" }
                    ]
                    },
                    { name: "User G", dob: "04/09/1989" },
                    { name: "User H", dob: "06/20/1963" }
                ]
                },
                { name: "User C", dob: "12/30/1977" },
                { name: "User D", dob: "10/27/1968" }
            ];

            private function dob_sort(itemA:Object, itemB:Object):int {
                var dateA:Date = itemA.dob ? new Date(itemA.dob) : null;
                var dateB:Date = itemB.dob ? new Date(itemB.dob) : null;
                return ObjectUtil.dateCompare(dateA, dateB);
            }

            private function dob_dataTip(item:Object):String {
                if (!item.hasOwnProperty('children') && item.hasOwnProperty("dob")) {
                    return dateFormatter.format(item.dob);
                }
                return null;
            }

            private function dob_label(item:Object, col:AdvancedDataGridColumn):String {
                if(!item.hasOwnProperty('children') && item.hasOwnProperty("dob")) {
                    return item.dob;
                }
                return null;
            }
        ]]>
    </mx:Script>

    <mx:DateFormatter id="dateFormatter" formatString="MMMM D, YYYY" />

    <mx:AdvancedDataGrid id="adgTest" dataProvider="{new HierarchicalData(arrData)}" designViewDataType="tree" width="746" height="400">
        <mx:columns>
            <mx:AdvancedDataGridColumn headerText="Name"  dataField="name"/>
            <mx:AdvancedDataGridColumn headerText="Date of birth" dataField="dob"
                labelFunction="dob_label" 
                dataTipFunction="dob_dataTip"
                sortCompareFunction="dob_sort"
                showDataTips="true" />

        </mx:columns>
    </mx:AdvancedDataGrid>
</mx:Application>
爱人如己 2024-07-13 02:48:00

虽然本例中的情况似乎并非如此,但列上缺少 dataField 将阻止排序发生。 系统正如所描述的那样,从未调用 sortCompareFunction。

如果您有一个自定义列渲染器,可以自行从数据中提取字段,则很容易忽略 dataField 属性的填充。 在这种情况下,一切都会正常进行,直到您进行排序。 sortCompareFunction 将不会被调用。

通过调试 HierarchicalCollectionView.as 进行检查,位于 sortCanBeApplied 中的第 1259 行左右。

While it doesn't appear to be the case in this example, a missing dataField on a column will prevent sort from happening. The systems are precisely as described, the sortCompareFunction is never called.

If you have a custom column renderer that is pulling fields out of data on its own, it's easy to overlook filling in a dataField attribute. Everything will work fine, in that case, until you go to sort. The sortCompareFunction will not be called.

Check by debuggging HierarchicalCollectionView.as, at line 1259 or so, in sortCanBeApplied.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文