使用RemoteObject发送的对象上达到的最大嵌套级别

时间:2014-04-08 12:03:08

标签: flex nested depth amf remoteobject

我们的Flex Web应用程序使用RemoteObject连接将自定义类对象发送到PHP。此对象具有多个深度级别,主要对象内嵌有嵌套对象。无论对象有多复杂,我们都发现允许的嵌套级别数有限制。到达时,RemoteObject在发送数据之前进行的序列化会因此错误而崩溃:

TypeError:错误#1034:类型强制失败:无法转换对象@ 7e30f89和mx.messaging.messages.IMessage。

如果我们发送一个较轻的对象(删除所有属性),则会发生同样的情况。例如:

var params:Object = {};
params['test'] = {0:{1:{2:{3:{4:{5:{6:{7:{8:{9:{10:{11:{12:{13:{14:{15:{16:{17:{18:{19:{20:{21:{22:{}}}}}}}}}}}}}}}}}}}}}}}};
remoteObject.runService(params);

如果对象的级别较低,则可以正常工作:

params['test'] = {0:{1:{2:{3:{4:{5:{6:{7:{8:{9:{10:{11:{12:{13:{14:{15:{16:{17:{18:{19:{20:{21:{}}}}}}}}}}}}}}}}}}}}}}};

看起来RemoteObject允许最大嵌套级别深度为24,可能是23.之后,它会崩溃。发送JSON不是一个选项,因为我丢失了主对象中的所有类型的类和对象。

有没有人知道如何面对这个?

提前致谢!

1 个答案:

答案 0 :(得分:0)

在树形结构中保留24个级别而不将树分成更易于管理的块,这不是一个非常可持续的想法。要将树转换为平面结构,您应该为树中的每个节点指定一个UID,一个子节点数组,如果需要,还可以为其父节点提供引用。

当您将展平的树发送到服务器时,然后序列化对象,以便发送到服务器的每个节点只是一个包含其UID及其子节点和父节点的UID的无类型对象。这是一个完全扁平的结构,不需要嵌套。当您从服务器读取时,您在客户端上重建树结构。

public class Node {
    public var uid:String;
    public var children:Array = [];
    public var parent:String;

    public function addChild(node:Node):void
        children.push(node);
        node.parent = this;
    }
}           

// Elsewhere..

// Convert tree nodes into flat array of raw objects
public function serialize(rootNode:Node):Array {
    // Remove tree structure.
    var flattenedNodes:Array = flatten(rootNode);

    // Convert to untyped objects using only string UIDs to identify children and parents.
    var untypedNodes:Array = [];
    for each (var node:Node in flattenedNodes) {
        var childIds:Array = [];
        for each (var child:Node in node.children) {
            childIds.push(child.uid);
        }

        var untypedNode:Object = {
            uid: node.uid,
            parent: node.parent ? node.parent.uid : null,
            children: childIds
        };
        untypedNodes.push(untypedNode);
    }

    return untypedNodes;
}

private function flatten(node:Node):Array {
    var result:Array = [node];
    for each (var child:Node in node.children) {
        result = result.concat(flatten(child));
    }
    return result;
}

// Convert a flat array of raw objects back into tree nodes
public function deserialize(items:Array):Node {
    var root:Node;
    var current:Node;
    var item:Object;
    var uidToNodeMap:Dictionary = new Dictionary();
    // Add all nodes to a map by uid
    for each (item in items) {
        current = new Node();
        current.uid = item.uid;
        uidToNodeMap[item.uid] = current;
        if (!item.parent) {
            root = current;
        }
    }
    // Build tree by replacing ids with actual nodes
    for each (item in items) {
        current = uidToNodeMap[item.uid];
        current.parent = uidToNodeMap[item.parent];
        for each (var childId:String in item.children) {
            current.children.push(uidToNodeMap[childId]);
        }
    }
}