Ext JS - Learning Center

Tutorial:Jayrock with Ext

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: This tutorial shows a basic usage of Jayrock library with Ext
Author: Tomislav Tustonic
Published: 2007-06-23
Ext Version: 1.1
Languages: en.png English

Contents

Jayrock

Jayrock is an open source (LGPL) implementation of JSON and JSON-RPC for the Microsoft .NET Framework, including ASP.NET. It creates JavaScript proxy classes for the server-side objects and methods, and allows the client script to call into server-side methods using JSON as the wire format and JSON-RPC as the procedure invocation protocol. The methods can be called synchronously or asynchronously.

To use Jayrock with Ext, we need to setup a server side, and create Ext classes to communicate with the server. So first is the server side stuff.

Server side

The server side part is a HttpHandler which inherits JsonRpcHandler class. The methods with JsonRpcMethod on them will be exported to our Javascript proxy class. Here's a simple example, a generic class with two methods:

public abstract class HandlerBase<T>: JsonRpcHandler
{
... 
  [JsonRpcMethod("getById", Idempotent=true)]       
  public virtual T GetById(long id)
  {        
    T ret = _dao.GetById(id) ;
    return ret;
  }
 
  [JsonRpcMethod("list", Idempotent=true)]
  public virtual Dictionary<string, object> List(int start, int limit, string sort, string dir)
  {
    int total ;
    NHibernate.Expression.Order[] os = null;
    if (!String.IsNullOrEmpty(sort)) 
    {
      os = new NHibernate.Expression.Order[1] ; 
      os[0] = new NHibernate.Expression.Order(sort, dir.ToLower() != "desc") ; 
    }
    IList<T> list = _dao.FindAll(start, limit, os, out total) ;
 
    Dictionary<string, object> ret = new Dictionary<string, object>() ;
    ret["total"] = total ;
    ret["data"] = list ;
    return ret ;
}
... etc ...
}

Here I am using a generic DAO, like the one described here: http://www.hibernate.org/328.html.

Also, I'm using server side sorting, so there are parameters sort and dir.

To have specific handlers, we just create something like myobjecthandler.ashx, with code like this:

[JsonRpcService("myObject")]
public class MyObjectHandler:HandlerBase<MyObject>
{
}

The methods we want exported to our client side are marked with JsonRpcMethod("list", Idempotent=true). The first argument ("list") is the name that our method will have on the client side. We'll rename our methods to camel case, to be consistent with JavaScript conventions. The argument Idempotent basically says that this method doesn't change anything on the server side, so it's safe to call it using REST syntax and GET, so we may use this like myobjecthandler.ashx/list

Client side setup

Now that we have or server side done, we can set our client side. Jayrock can use its own Ajax calls, or it can use any existing library to do its work. We will use Ext implementation, to simplify our life, and to reduce code size and dependecies. However, unlike Ext, Jayrock can use synchronous calls, so somebody might like it.

To use Jayrock Ajax, we put something like this on top:

<script type="text/javascript" src="handlers/myobjecthandler.ashx?proxy"></script>

For Ext we use this form:

<script type="text/javascript" src="handlers/myobjecthandler.ashx?proxy&v=2"></script>

If we look at the Jayrock generated proxy, we'll see something like this:

var myObject = function()
{
    var nextId = 0;
 
    var proxy = {
        url : "http://...blabla.../myobjecthandler.ashx",
        rpc : {            
            "getById" : function(id, callback) {
                return new Call("getById", [ id ], callback);
            },            
            "list" : function(start, limit, sort, dir, meta, callback) {
                return new Call("list", [ start, limit, sort, dir, meta ], callback);
            }
        }

So, we have our handler and methods with correct names.

Ext code

To use this stuff in Grid, we need a DataProxy to be used with the Grid.

Tom.JsonRpcProxy = function(jsonRpcProxy, listMethod) 
{
    var _jsonRpcProxy = null ; 
    var _listMethod = null;
 
    Tom.JsonRpcProxy.superclass.constructor.call(this);        
 
    this.load = function(params, reader, callback, scope, arg) {
        _jsonRpcProxy[listMethod] (params.start, params.limit, params.sort, params.dir, 
            this.loadResponse.createDelegate(this, [reader, callback, scope, arg], true ) 
        ).call(Tom.JsonRpcProxy.ext_channel1); 
    }
 
    this.loadResponse = function(response, reader, callback, scope, arg) {
        var result;
        result = reader.read(response) ;
        callback.call(scope||this, result, arg, true) ;
    }
 
    this.setRpcProxy = function(jsonRpcProxy, listMethod)  {
        if (isDefined(jsonRpcProxy))
            _jsonRpcProxy = jsonRpcProxy.rpc || jsonRpcProxy ;
        _listMethod = listMethod || "list"  ; 
    }    
    this.setRpcProxy(jsonRpcProxy, listMethod) ;    
} ;
 
Tom.JsonRpcProxy.ext_channel1 = function(call)
{
    if (typeof(call.callback) !== 'function')
        throw new Error("The EXT channel does not support synchronous methods.");        
    call.yuiconn = Ext.Ajax.request (
        {
            url: call.url , 
            params: {"JSON-RPC": Ext.util.JSON.encode(call.request)} , 
            success: function(response, options) {
                    call.callback(response) ;
                },                            
            failure: function(response, options) {
                    call.callback({xhr:response}); 
                }   
        }
    );
    return call ; 
} ;
 
Tom.JsonRpcProxy.ext_channel2 = function(call)
{
    if (typeof(call.callback) !== 'function')
        throw new Error("The EXT channel does not support synchronous methods.");        
    call.yuiconn = Ext.lib.Ajax.request("POST", call.url, {
            success: function(response) {
                    return call.callback(response) ;     // Jsonreader
                },
            failure: function(response) { 
                call.callback({xhr: response}); 
            }
        },
        "JSON-RPC=" + encodeURIComponent(Ext.util.JSON.encode(call.request))
    );
    return call ; 
} ;
 
Ext.extend(Tom.JsonRpcProxy, Ext.data.DataProxy, {
}) ;

We are using server side sorting,

Here _jsonRpcProxy is the proxy object generated by Jayrock (myObject in our example). _listMethod is the name of the method which gets the list of data. If the method always has the same name (for example getAll , the code above can be simplified, from _jsonRpcProxy[listMethod] to _jsonRpcProxy.getAll

Also, here are defined two different channels to use with our Jayrock calls. They are made public, so that other calls to Jayrock proxy can use them. At this moment both of them seem to work, so only one of them is needed in production code, other can be removed.

And, finally, let's create a Store. We'll create our proxy and setup a JsonReader for our data:

function _createDataStore() {
    var px = new Tom.JsonRpcProxy(myObject.rpc, "list") ;
    var rdr = new Ext.data.JsonReader
       ({root: 'result.data', totalProperty: 'result.total', id: 'id'}) ;
    var ds = new Ext.data.Store({proxy: px, reader:rdr, remoteSort:true}) ;
    return ds ;
}

Plug this store into the Grid and that's it.

Obviously, the Jayrock proxy has some more methods, and they can be used like this:

myObject.rpc.getById('1234', function(r) {
   /* some stuff */ 
} ).call(Tom.JsonRpcProxy.ext_channel1);   // or ext_channel2
  • This page was last modified on 23 July 2007, at 18:33.
  • This page has been accessed 19,184 times.