Flex中数据管理的基本原则

时间:2011-07-29 20:02:07

标签: flex data-binding air

我不确定我的标题是否真的反映了这里发生的事情......我刚才意识到我显然错过了Flex处理数据(内存?)的基本原则,我需要一些帮助理解它。

我有一个名为friends的MySQL表,其中包含以下行;

MySQL table friends
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Mark      | Smith    |
| Andrew    | Barnes   |
+-----------+----------+

在下一个例子中,我正在调用我的friendsService.getAllFriends()三次然后,我将结果分配给三个不同DataGrids的DataProvider。

第二次向数据库发送查询时,我只是在将结果分配给DataProvider之前将Mark的名字改为Peter。我不是以任何方式更新数据库,对吧? : - )

我的期望:

MyDataGrid1
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Mark      | Smith    |
| Andrew    | Barnes   |
+-----------+----------+

MyDataGrid2
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Peter     | Smith    | <---- Say hello to Peter :-)
| Andrew    | Barnes   |
+-----------+----------+

MyDataGrid3
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Mark      | Smith    |
| Andrew    | Barnes   |
+-----------+----------+

在调用第二个查询(我以编程方式将Mark切换到Peter)后,看起来所有三个结果都以某种方式绑定我不理解 ...我获得:< / p>

MyDataGrid1
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Peter     | Smith    |
| Andrew    | Barnes   |
+-----------+----------+

MyDataGrid2
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Peter     | Smith    |
| Andrew    | Barnes   |
+-----------+----------+

MyDataGrid3
+-----------+----------+
| firstname | lastname |
+-----------+----------+
| Peter     | Smith    |
| Andrew    | Barnes   |
+-----------+----------+

看起来Flex并不是真的要求新数据,假设它已经有来自friendsService.getAllFriends()的答案......

对我有什么启发? : - )

感谢!

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:friendsservice="services.friendsservice.*"
    creationComplete="creationCompleteHandler(event)">

    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            import mx.rpc.events.ResultEvent;

            private var _step:Number = 1;

            protected function creationCompleteHandler(event:FlexEvent):void
            {
                getAllFriends();
            }

            protected function getAllFriends():void
            {
                getAllFriendsResult.token = friendsService.getAllFriends();
            }

            protected function getAllFriendsResult_resultHandler(event:ResultEvent):void
            {

                if (_step == 1) {
                    assignValuesToDataGrid(MyDataGrid1, event.result, _step);
                    dbg.text = "MyDataGrid1 has been loaded";
                }

                if (_step == 2) {
                    assignValuesToDataGrid(MyDataGrid2, event.result, _step);
                    dbg.text = "MyDataGrid2 has been loaded";
                }

                if (_step == 3) {
                    assignValuesToDataGrid(MyDataGrid3, event.result, _step);
                    dbg.text = "MyDataGrid3 has been loaded";
                }

                _step++;
            }

            protected function assignValuesToDataGrid(dg:DataGrid, result:Object, step:Number):void
            {
                if (step == 2)
                    result[0].firstname = "Peter";

                dg.dataProvider = result;
            }

        ]]>
    </fx:Script>

    <fx:Declarations>
        <s:CallResponder id="getAllFriendsResult" result="getAllFriendsResult_resultHandler(event)"/>
        <friendsservice:FriendsService id="friendsService"/>
    </fx:Declarations>

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <s:Button label="Load next DataGrid" click="getAllFriends()"/>

    <mx:DataGrid id="MyDataGrid1" width="100%" height="100">
        <mx:columns>
            <mx:DataGridColumn headerText="First name" dataField="firstname"/>
            <mx:DataGridColumn headerText="Last name" dataField="lastname"/>
        </mx:columns>
    </mx:DataGrid>

    <mx:DataGrid id="MyDataGrid2" width="100%" height="100">
        <mx:columns>
            <mx:DataGridColumn headerText="First name" dataField="firstname"/>
            <mx:DataGridColumn headerText="Last name" dataField="lastname"/>
        </mx:columns>
    </mx:DataGrid>

    <mx:DataGrid id="MyDataGrid3" width="100%" height="100">
        <mx:columns>
            <mx:DataGridColumn headerText="First name" dataField="firstname"/>
            <mx:DataGridColumn headerText="Last name" dataField="lastname"/>
        </mx:columns>
    </mx:DataGrid>

    <s:Label id="dbg" fontWeight="bold"/>

</s:WindowedApplication>

2 个答案:

答案 0 :(得分:2)

FriendService正在使用AbstractEntityMetadata来管理实体。所以,我认为它是根据它的ID合并朋友。

我的意思是,让我们说Mark有id 1,因为它是一个托管实体,当你对服务器进行新的调用时,它首先搜索匹配id为1的实例并更新它,而不是创建新对象。这就是为什么所有三个数据网格具有相同的对象。

答案 1 :(得分:1)

经过多次测试后,我想我发现了正在发生的事情。

使用“连接到数据/服务”工具生成服务时,使用“生成样本”选项时,Flash Builder会自动启用“数据管理”选项。

让我们看一下文件 /src/services/friendservice/_Super_FriendService.as ,我们在哪里:

var dmOperation : mx.data.ManagedOperation;
var dmQuery : mx.data.ManagedQuery;

dmQuery = new mx.data.ManagedQuery("getAllFriends");
dmQuery.propertySpecifier = "id,firstname,lastname";
dmQuery.parameters = "";
_friendsRPCDataManager.addManagedOperation(dmQuery);

dmOperation = new mx.data.ManagedOperation("deleteFriends", "delete");
dmOperation.parameters = "id";
_friendsRPCDataManager.addManagedOperation(dmOperation);     

dmOperation = new mx.data.ManagedOperation("getFriendsByID", "get");
dmOperation.parameters = "id";
_friendsRPCDataManager.addManagedOperation(dmOperation);     

dmOperation = new mx.data.ManagedOperation("updateFriends", "update");
dmOperation.parameters = "item";
_friendsRPCDataManager.addManagedOperation(dmOperation);     

dmOperation = new mx.data.ManagedOperation("createFriends", "create");
dmOperation.parameters = "item";
_friendsRPCDataManager.addManagedOperation(dmOperation);

现在,让我们用自定义对象替换“连接到数据/服务”工具生成的ValueObject。

通过选择自动检测样本数据中的返回类型选项,Flash Builder将查询数据库,收集字段类型并相应地配置值对象。现在让我们再看一下我们的_Super_FriendService.as:

var dmOperation : mx.data.ManagedOperation;
var dmQuery : mx.data.ManagedQuery;

dmOperation = new mx.data.ManagedOperation("deleteFriends", "delete");
dmOperation.parameters = "id";
_friendsRPCDataManager.addManagedOperation(dmOperation);     

dmOperation = new mx.data.ManagedOperation("getFriendsByID", "get");
dmOperation.parameters = "id";
_friendsRPCDataManager.addManagedOperation(dmOperation);     

dmOperation = new mx.data.ManagedOperation("updateFriends", "update");
dmOperation.parameters = "item";
_friendsRPCDataManager.addManagedOperation(dmOperation);     

dmOperation = new mx.data.ManagedOperation("createFriends", "create");
dmOperation.parameters = "item";
_friendsRPCDataManager.addManagedOperation(dmOperation);

惊喜,dmQuery = new mx.data.ManagedQuery("getAllFriends");块不再存在......我们知道我们可以为以下操作禁用数据管理(创建(添加)项目,获取项目,更新项目和删除项目)。

因此,通过使用自定义ValueObject,我们与生成的ValueObject具有完全相同的信息,而现在没有阻止我2天的块。我很高兴我找到了一个真正彻底禁用数据管理的解决方法。