编辑 | blame | 历史 | 原始文档

Using AMF Data in Ext JS

Action Message Format (AMF)
is a compact binary format used by Adobe Flash/Flex to serialize ActionScript
object graphs. AMF is typically used to encode messages that are sent between
an Adobe Flash client and a remote service. AMF is only a serialization
technology, not a transport, so AMF encoded binary data can be used with any
transport such as HTTP or HTTPS. This guide will show you how to use Ext JS and
AJAX to consume AMF data sent over HTTP right inside a web browser, with no need
for a Flash plugin. This guide assumes you are already somewhat familiar with
the Ext JS Data Package and Grids.

Working with AMF Packets

AMF-encoded object graphs are typically formatted as an "AMF Packet". Multiple
headers and messages are batched into a single AMF Packet. Lets take a look at
how to use Ext JS to decode an AMF Packet and access its headers and messages.
First lets make an AJAX request to a url that returns binary AMF Packet data.

Ext.Ajax.request({
    url: 'some/url',
    binary: true,
    success: function(response) {
        console.log(response.responseBytes);
    }
});

You should see a byte array in your console - either a Uint8Array if it is
supported by your browser or just an Array of numbers. These are the raw
bytes that compose the AMF Packet. It is important to remember to set the
{@link Ext.data.Connection#binary binary} config to true on the AJAX request
so that the response will be interpreted as binary data and the responseBytes
property will be set on the response object.

Now that we have the raw binary data we need to decode it so that we can do
something useful with it. To do this we use the {@link Ext.data.amf.Packet}
class. Inside the success callback function add the following code to construct
a new Packet:

var packet = Ext.create('Ext.data.amf.Packet');

This gives us an empty AMF Packet object to work with. The Packet class contains
all the logic required to decode the binary AMF-formatted data. To decode the
AMF byte array, simply pass it to the Packet's
{@link Ext.data.amf.Packet#decode decode} method:

packet.decode(response.responseBytes);

We now have a fully decoded AMF Packet. The decoded data can be accessed using
the following properties on the packet object:

  • {@link Ext.data.amf.Packet#version version} - The Packet's AMF version
  • {@link Ext.data.amf.Packet#headers headers} - The Packet's headers
  • {@link Ext.data.amf.Packet#messages messages} - The Packet's messages

Loading records into a Grid

Now that we know how to use the AMF Packet, lets learn how to load some
AMF-encoded records into an Ext JS {@link Ext.data.Store Store} using an
{@link Ext.data.amf.Proxy AMF Proxy} and {@link Ext.data.amf.Reader AMF Reader}
and display those records in a {@link Ext.grid.Panel Grid}. In this example we
will load records from an AMF Packet containing a list of pangrams in several
languages. Start by defining the {@link Ext.data.Model Model}:

Ext.define('Pangram', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'language', type: 'string' },
        { name: 'text', type: 'string' }
    ]
});

Next create a {@link Ext.data.Store Store} to contain the Model instances.
Configure the store with an {@link Ext.data.amf.Proxy AMF Proxy}. The AMF Proxy
uses an {@link Ext.data.amf.Reader AMF Reader} by default so there is no need
to explicitly configure the reader unless you need to change some of the reader's
default configurations.

var store = Ext.create('Ext.data.Store', {
    model: 'Pangram',
    proxy: {
        type: 'amf',
        url: 'some/url',
    },
    autoLoad: true
});

Finally create a {@link Ext.grid.Panel Grid} that is bound to the store we just
created:

Ext.create('Ext.grid.Panel', {
    title: 'AMF0 Pangrams',
    height: 350,
    width: 700,
    store: store,
    columns: [
        { text: 'Language', dataIndex: 'language', width: 130 },
        { text: 'Pangram', dataIndex: 'text', flex: 1 }
    ],
    renderTo: Ext.getBody()
});

{@img amf-grid.png AMF Grid}

The above code makes some assumptions about where the raw record data are located
within the packet. By default {@link Ext.data.amf.Reader AMF Reader} expects
the Packet's first message body to be an array of objects containing the record
data. But this is not always the case - sometimes you need to tell the reader
where to find the records in the message body. This is done using the reader's
{@link Ext.data.Reader#root root} configuration property:

proxy: {
    type: 'amf',
    url: 'some/url',
    reader: {
        type: 'amf',
        root: 'foo.bar'
    }
}

This tells the reader that the message body is an object containing a property
named "foo" which is an object containing a property named "bar", and the value
of "bar" is an array of raw record data objects.

AMF Packets can contain multiple messages. You can configure which message the
reader should look for the records in using the
{@link Ext.data.amf.Reader#messageIndex messageIndex} config:

reader: {
    type: 'amf',
    messageIndex: 42
}

For a working example and full source code see AMF Grid Example