Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    GWT-RPC Datasource template

    I found myself writing a lot of boilerplate code for my DataSources that used GWT-RPC calls. Most of this code involves maintaining the internal data state of the DataSource and dependent widgets in the face of a possible failure occurring asynchronously after transformResponse is called.

    I've wrapped this code up into a reusable class, GwtRpcDataSource, with a helper class GwtRpcDataSourceEndpoint.

    You can set up to four endpoints on the datasource (fetch,add,update,remove).
    In each endpoint you must implement call endpoint. This is where you call your GWT-RPC service.
    You must pass the service the callback provided by the callEndpoint interface.
    If you are implementing an add/update/remove endpoint the first parameter in the variable arguments list will be the ListGridRecord being affected. If you are using bulkMode the first parameter will instead be a ListGridRecord array.
    If you are implementing the fetch command, it is assumed that your GWT-RPC call will return a Collection<T> where T is the type parameter you gave your GwtRpcdDataSource. If this is not true you must implement the transformResult object which will let you transmute the result Object into a Collection<T>.
    You must implement populateRecord on your GwtRpcDataSource, this is where you set the attributes of a record object with the data from your parametrized type T.
    The remaining parameters are whatever data you choose to cache on your GwtRpcDataSource via the setParameters call. This allows you to cache arbitrary data you may need to send to all your invocations.

    I've also included a sample implementation to make this more clear.
    Last edited by Isomorphic; 23 Mar 2009, 13:05.

    #2
    GwtRpcDataSource

    I couldn't include all the source for the datasource in one post so I made attachments instead.
    Attached Files

    Comment


      #3
      I've just tried it. It works nicely, and it makes my own "hack" seem overcomplicated.
      I will use this code while waiting for the official SmartGWT solution.

      Thanks Ben, this is a nice effort for the community.

      Comment


        #4
        Thanks Benjamin, I'm sure other users will find this very useful.

        Comment


          #5
          Thank you for taking the time to do this. It is greatly appreciated.

          Comment


            #6
            Thanks Ben, that's definitely the most complete and easiest to re-use example that anyone's posted to date. We'll mark this thread sticky.

            Comment


              #7
              Problems in updating DataSource

              Thank you Benjamin for your code, I was searching this kind of solution in managing smartclient datasources.

              So I used your code and created my DataSource extending GwtRpcDataSource<T>.

              But now I have a strange problem...
              I have got a Panel with 2 tabs inside. The first tab contains a ListGrid attached to our DataSource called CategorieVociBaseDS (which extends GwtRpcDataSource<CategorieVociBase>). On double click on a record row another tab is opened with a dynamic form bounded to the same DataSource.
              At the bottom of the dynamic form there is a "save" button calling the form saveData method.

              All endpoints seem correctly called but after changing a record in the dynamic form and saving the record the datasource seems not changed.
              So apparently I have a read only data source. The fetch populates correclty the list grid at the beginning but no other changes are tracked.

              Any ideas about this behaviour?
              I attached CategorieVociBaseDS and CategorieVociPanel
              Attached Files

              Comment


                #8
                I found the problem

                Just call:

                Code:
                callback.onSuccess(record);
                inside the method:

                Code:
                setUpdateEndpoint(new GwtRpcDataSourceEndpoint<CategorieVociBase>() {
                
                			@Override
                			public void callEndpoint(AsyncCallback callback, Object... parameters) {
                				ListGridRecord record = (ListGridRecord) parameters[0];
                				callback.onSuccess(record);
                			}});

                Comment


                  #9
                  do you think this could be used to lazy load records only when displaying them?

                  Comment


                    #10
                    Impiastro,

                    You're right there is a bug there. More broadly things don't behave correctly if remove/add/update is used and no endpoint (or the endpoint does not use the callback) is set. I will update the base class to correct this problem.

                    Mihai007,

                    I haven't tried myself but this was something I wanted to look into this weekend.

                    I plan to change the signature of callEndpoint to make the DSRequest available to the callbacks in case the request is used for advanced control. I plan to change the signature for remove/add/update so that the record or record array are available outside of the parameters list so that you can use the same indices for input and output. I also left some embarrassing dead code in that I need to pull out.

                    If anyone has any other use cases it would be interesting to consider let me know. I plan to post a revised version this weekend.

                    Benjamin

                    Comment


                      #11
                      Originally posted by benjaminberry
                      I plan to post a revised version this weekend.
                      Could you add that to smartgwt-extensions ?
                      http://code.google.com/p/smartgwt-extensions

                      I could set up automated builds plus a Maven repository, enabling us to get updates automatically.

                      Comment


                        #12
                        In the example code, the addStock and editStock methods only take the stock symbol as parameter, like this:
                        Code:
                         stockService.addStock(record.getAttribute("symbol"), callback);     
                        
                        stockService.editStock(record.getAttributeAsInt("id"), record.getAttribute("symbol"), callback);
                        As far as I see, the stock service will not be able to edit or create stock prices with this information only.

                        Wouldn't the example be more realistic if those methods took a StockPrice object instead, created inside the callEndpoint methods? Or is it something I missed?

                        Comment


                          #13
                          Pagination and filters

                          Hi, I'm using this solution and it's quite stable and simple. But I haven't still figured out how I can manage pagination and filters in the fetch endpoint.
                          Can someone give me some hints about this.
                          Thank you

                          Bit

                          Comment


                            #14
                            How about TreeGrids?

                            Has anybody been able to make this work with TreeGrid?

                            Comment


                              #15
                              Can you provide any example, how to pass startrow, endrow parameter from datasource to callback, please?

                              My result contains more than 50k rows, and it hangs browser.

                              Comment

                              Working...
                              X