Facebook Graph API Development with Flash
上QQ阅读APP看书,第一时间看更新

Time for action - rendering Lists of Posts

Since a Graph List's data property is an array of Graph Objects, we could just loop through the array and create a new Graph Object Renderer for each element. Feel free to have a go at this, if you like, but I've got another solution.

I've created a second renderer: this time, a Graph List Renderer. I've also created a class graph.GraphList. And CustomGraphContainerController inherits a method called renderGraphList(). Perhaps unsurprisingly, this takes an object of type graph.GraphList as a parameter, and creates a new Graph List Renderer to display its contents. So, we need to take a Graph List that we receive from the Graph API, and turn it into an instance of the GraphList class. The GraphList class is a little more sophisticated than the GraphObject class; it has a method called addToList(), to which we can pass any GraphObject instance to be added to the list.

We'll still loop through the data array, then, but instead of rendering each GraphObject on its own, we'll add each one to a GraphList and render that.

Modify the URL that CustomGraphContainerController requests, so that it loads the list of posts:

public function CustomGraphContainerController (a_graphControlContainer:GraphControlContainer)
{
super(a_graphControlContainer);
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest();
//Specify which Graph URL to load
request.url = "https://graph.facebook.com/PacktPub/posts";
loader.addEventListener(Event.COMPLETE, onGraphDataLoadComplete);
//Start the actual loading process
loader.load(request);
}

Now, once this is loaded, we need to check whether the item returned is a Graph Object or a Graph List. We can do this by looking for a property called data; if one exists, we'll assume it's a List.

private function onGraphDataLoadComplete(a_event:Event):void
{
var loader:URLLoader = a_event.target as URLLoader;
//obtain whatever data was loaded, and trace it
var graphData:String = loader.data;
var decodedJSON:Object = JSON.decode(graphData);
if (decodedJSON.data) { //has a "data" property so we assume it is a Graph List } else { //no "data" so we assume it is a Graph Object
var graphObject:GraphObject = new GraphObject();
//copy all the properties from decodedJSON to graphObject
for (var key:String in decodedJSON)
{
graphObject[key] = decodedJSON[key];
}
this.renderGraphObject(graphObject);
}
}

Inside this if block, we first create a new GraphList instance:

if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
}

(You will need to import graph.GraphList.)

Next, remember than decodedJSON.data is an array of objects; we loop through this array, and create a GraphObject from each element.

if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
var childGraphObject:GraphObject;
for each (var childObject:Object in decodedJSON.data)
{
childGraphObject = new GraphObject();
for (var childKey:String in childObject)
{
childGraphObject[childKey] = childObject[childKey];
}
}
}

This is basically the same thing we did with the decodedJSON when loading a single Graph Object.

What about the other property inside the Graph List, the paging object? We should add that too:

if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
var childGraphObject:GraphObject;
for each (var childObject:Object in decodedJSON.data)
{
childGraphObject = new GraphObject();
for (var childKey:String in childObject)
{
childGraphObject[childKey] = childObject[childKey];
}
graphList.addToList(childGraphObject);
}
graphList.paging = decodedJSON.paging;
}

Finally, we pass the GraphList instance to renderGraphList():

if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
var childGraphObject:GraphObject;
for each (var childObject:Object in decodedJSON.data)
{
childGraphObject = new GraphObject();
for (var childKey:String in childObject)
{
childGraphObject[childKey] = childObject[childKey];
}
graphList.addToList(childGraphObject);
}
graphList.paging = decodedJSON.paging;
this.renderGraphList(graphList);
}

Compile the SWF and test it. The following screenshot shows the result:

Time for action - rendering Lists of Posts

It's a scrollable window containing all the Graph Objects from the list.

What happens when you click the Pop Out button underneath a Graph Object?

Time for action - rendering Lists of Posts

What just happened?

The Graph Object pops out into its own Graph Object Renderer, with a gray line connecting it to the list to which it belongs. This lets you look at several children of a list at the same time:

What just happened?

(You can drag the individual renderers to reposition them, or drag the background to move everything at once.)

This makes it clear that a Graph List is just a collection of Graph Objects.

Rendering connections

We've shown the link from a Graph List to its Graph Objects; the next step is to show the connections from a Graph Object to its Graph Lists.