Extjs复习笔记(十五)-- JsonReader

使用JsonReader来创建grid中的store (examples/grid/binding)


Extjs复习笔记(十五)-- JsonReader

下面程序中,绿色的注释大都是API中的解释,有助于理解,我把它直接加上程序中了

Ext.onReady(function(){

    var store = new Ext.data.Store({
        remoteSort: true, //用下面的代理proxy默认的数据顺序来排序,详细:
/*true if sorting is to be handled by requesting the Proxy to provide a refreshed version of the data object in sorted order, as opposed to sorting the Record cache in place (defaults to false).
If remoteSort is true, then clicking on a Grid Column's header causes the current page to be requested from the server appending the following two parameters to the params:
sort : String
The name (as specified in the Record's Field definition) of the field to sort on.
dir : String
The direction of the sort, 'ASC' or 'DESC' (case-sensitive).*/
        baseParams: {lightWeight:true,ext: 'js'}, //要做为参数传给服务器
/*baseParams:An object containing properties which are to be sent as parameters for every HTTP request.
Parameters are encoded as standard HTTP parameters using Ext.urlEncode.
Note: baseParams may be superseded by any params specified in a load request, see load for more details.
This property may be modified after creation using the setBaseParam method.*/
        sortInfo: {field:'lastpost', direction:'DESC'},  //排序用的一些参数
/*sortInfo:A config object to specify the sort order in the request of a Store's load operation. Note that for local sorting, the direction property is case-sensitive. See also remoteSort and paramNames. For example:
sortInfo: {
    field: 'fieldName',
    direction: 'ASC' // or 'DESC' (case sensitive for local sorting)
}*/
        autoLoad: {params:{start:0, limit:500}},
/*autoLoad:If data is not specified, and if autoLoad is true or an Object, this store's load method is automatically called after creation. If the value of autoLoad is an Object, this Object will be passed to the store's load method.*/

        proxy: new Ext.data.ScriptTagProxy({ //The DataProxy object which provides access to a data object.
            url: 'http://extjs.com/forum/topics-browse-remote.php'
        }),
/*ScriptTagProxy:An implementation of Ext.data.DataProxy that reads a data object from a URL which may be in a domain other than the originating domain of the running page.
Note that if you are retrieving data from a page that is in a domain that is NOT the same as the originating domain of the running page, you must use this class, rather than HttpProxy.
The content passed back from a server resource requested by a ScriptTagProxy must be executable JavaScript source code because it is used as the source inside a <script> tag.
In order for the browser to process the returned data, the server must wrap the data object with a call to a callback function, the name of which is passed as a parameter by the ScriptTagProxy. Below is a Java example for a servlet which returns data for either a ScriptTagProxy, or an HttpProxy depending on whether the callback name was passed:

boolean scriptTag = false;
String cb = request.getParameter("callback");
if (cb != null) {
    scriptTag = true;
    response.setContentType("text/javascript");
} else {
    response.setContentType("application/x-json");
}
Writer out = response.getWriter();
if (scriptTag) {
    out.write(cb + "(");
}
out.print(dataBlock.toJsonString());
if (scriptTag) {
    out.write(");");
}

Below is a PHP example to do the same thing:

$callback = $_REQUEST['callback'];

// Create the output object.
$output = array('a' => 'Apple', 'b' => 'Banana');

//start output
if ($callback) {
    header('Content-Type: text/javascript');
    echo $callback . '(' . json_encode($output) . ');';
} else {
    header('Content-Type: application/x-json');
    echo json_encode($output);
}

Below is the ASP.Net code to do the same thing:

String jsonString = "{success: true}";
String cb = Request.Params.Get("callback");
String responseString = "";
if (!String.IsNullOrEmpty(cb)) {
    responseString = cb + "(" + jsonString + ")";
} else {
    responseString = jsonString;
}
Response.Write(responseString);*/

        reader: new Ext.data.JsonReader({
            root: 'topics', //必写项,对应json数据中的一个array,数组
            totalProperty: 'totalCount',
/*totalProperty:Name of the property from which to retrieve the total number of records in the dataset. This is only needed if the whole dataset is not passed in one go, but is being paged from the remote server. Defaults to total.*/
            idProperty: 'threadid', //主键名
            fields: [ //要取出的各个字段
                'title', 'forumtitle', 'forumid', 'author',
                {name: 'replycount', type: 'int'},
                {name: 'lastpost', mapping: 'lastpost', type: 'date', dateFormat: 'timestamp'},
                'lastposter', 'excerpt'
            ]
        })
    });

    var grid = new Ext.grid.GridPanel({
        renderTo: 'topic-grid',
        width:700,
        height:500,
        frame:true,
        title:'ExtJS.com - Browse Forums',
        trackMouseOver:false,//True to highlight rows when the mouse is over. Default is true for GridPanel, but false for EditorGridPanel.
		autoExpandColumn: 'topic',
/*autoExpandColumn:The id of a column in this grid that should expand to fill unused space. This value specified here can not be 0.

Note: If the Grid's view is configured with forceFit=true the autoExpandColumn is ignored. See Ext.grid.Column.width for additional details.*/
        store: store,

        columns: [new Ext.grid.RowNumberer({width: 30}),//行号
       {
            id: 'topic',
            header: "Topic",
            dataIndex: 'title', //json数据中对应的数据的索引
            width: 420,
            renderer: renderTopic, //这是非常重要的一个属性,renderTopic是下面的一个函数,用来格式化本列,从下面的函数可以看出,本列显示的是一些链接和几个数据的组合
            sortable:true
        },{
            header: "Replies",
            dataIndex: 'replycount',
            width: 70,
            align: 'right', //这个属性也很重要,用来对齐数据
            sortable:true
        },{
            id: 'last',
            header: "Last Post",
            dataIndex: 'lastpost',
            width: 150,
            renderer: renderLast, //renderLast是下面的一个函数
            sortable:true
        }],

	    bbar: new Ext.PagingToolbar({ //bbar就是grid最下方的工具条,PagingToolbar是用来分页的一个实用的工具,下面详细解释
		    store: store,
		    pageSize:500,
		    displayInfo:true //true to display the displayMsg (defaults to false)
	    }),
/*PagingToolbar:As the amount of records increases, the time required for the browser to render them increases. Paging is used to reduce the amount of data exchanged with the client. Note: if there are more records/rows than can be viewed in the available screen area, vertical scrollbars will be added.

Paging is typically handled on the server side (see exception below). The client sends parameters to the server side, which the server needs to interpret and then respond with the approprate data.

Ext.PagingToolbar is a specialized toolbar that is bound to a Ext.data.Store and provides automatic paging control. This Component loads blocks of data into the store by passing paramNames used for paging criteria.

PagingToolbar is typically used as one of the Grid's toolbars:

Ext.QuickTips.init(); // to display button quicktips

var myStore = new Ext.data.Store({
    reader: new Ext.data.JsonReader({
        totalProperty: 'results', 
        ...
    }),
    ...
});

var myPageSize = 25;  // server script should only send back 25 items at a time

var grid = new Ext.grid.GridPanel({
    ...
    store: myStore,
    bbar: new Ext.PagingToolbar({
        store: myStore,       // grid and PagingToolbar using same store
        displayInfo: true,
        pageSize: myPageSize,
        prependButtons: true,
        items: [
            'text 1'
        ]
    })
});
To use paging, pass the paging requirements to the server when the store is first loaded.

store.load({
    params: {
        // specify params for the first page load if using paging
        start: 0,          
        limit: myPageSize,
        // other params
        foo:   'bar'
    }
});
If using store's autoLoad configuration:

var myStore = new Ext.data.Store({
    autoLoad: {params:{start: 0, limit: 25}},
    ...
});
The packet sent back from the server would have this form:

{
    "success": true,
    "results": 2000, 
    "rows": [ // *Note: this must be an Array 
        { "id":  1, "name": "Bill", "occupation": "Gardener" },
        { "id":  2, "name":  "Ben", "occupation": "Horticulturalist" },
        ...
        { "id": 25, "name":  "Sue", "occupation": "Botanist" }
    ]
}
Paging with Local Data

Paging can also be accomplished with local data using extensions:

Ext.ux.data.PagingStore
Paging Memory Proxy (examples/ux/PagingMemoryProxy.js)*/

	    view: new Ext.ux.grid.BufferView({ //view:The Ext.grid.GridView used by the grid. This can be set before a call to render(). ..... BufferView:是自定义的一个类,下面我把定义这个类的文件上传了。其实这个也可以到源码中的examples/ux/BufferView.js上找到
		    // custom row height
		    rowHeight: 34,
		    // render rows as they come into viewable area.
		    scrollDelay: false
	    })
    });


    // render functions
    function renderTopic(value, p, record){//本函数用来格式化列中数据显示的格式
        return String.format(//下面的{0} {1} {2}等分别对应下面列出的数据
                '<b><a href="http://extjs.com/forum/showthread.php?t={2}" target="_blank">{0}</a></b><a href="http://extjs.com/forum/forumdisplay.php?f={3}" target="_blank">{1} Forum</a>',
                value, record.data.forumtitle, record.id, record.data.forumid);
    }
    function renderLast(value, p, r){
        return String.format('{0}<br/>by {1}', value.dateFormat('M j, Y, g:i a'), r.data['lastposter']);
    }

});