1. #1
    Sencha User
    Join Date
    Apr 2011
    Posts
    40
    Vote Rating
    1
    liondev is on a distinguished road

      0  

    Default RequestFactoryProxy on Grid with RemoteSort

    RequestFactoryProxy on Grid with RemoteSort


    Hi there.

    I am trying to make an example of RequestFactoryProxy on Grid works, and almost is fine. I am getting an error when i try to sort a column.

    This the stack trace:
    PHP Code:
    19:13:35.149 [ERROR] [pruebasUncaught exception escaped
    java
    .lang.IllegalArgumentExceptioncom.sencha.gxt.data.shared.SortInfoBean    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.checkStreamsNotCrossed(AbstractRequestContext.java:972)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.editProxy(AbstractRequestContext.java:509)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.edit(AbstractRequestContext.java:502)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.retainArg(AbstractRequestContext.java:1230)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.retainArg(AbstractRequestContext.java:1226)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.access$2(AbstractRequestContext.java:1223)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$StandardPayloadDialect.addInvocation(AbstractRequestContext.java:289)    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.addInvocation(AbstractRequestContext.java:661)    at mx.com.liondev.pruebas.client.RequestFactory.PruebasRequestImpl.getEmployees(PruebasRequestImpl.java:77)    at mx.com.liondev.pruebas.client.Main$1.load(Main.java:108)    at mx.com.liondev.pruebas.client.Main$1.load(Main.java:1)    at com.sencha.gxt.data.shared.loader.RequestFactoryProxy.load(RequestFactoryProxy.java:24)    at com.sencha.gxt.data.shared.loader.Loader.loadData(Loader.java:235)    at com.sencha.gxt.data.shared.loader.Loader.load(Loader.java:183)    at com.sencha.gxt.data.shared.loader.Loader.load(Loader.java:168)    at com.sencha.gxt.widget.core.client.grid.GridView.doSort(GridView.java:1357)    at com.sencha.gxt.widget.core.client.grid.GridView.onHeaderClick(GridView.java:2129)    at com.sencha.gxt.widget.core.client.grid.GridView$7.onHeaderClick(GridView.java:1721)    at com.sencha.gxt.widget.core.client.grid.ColumnHeader$Head.onClick(ColumnHeader.java:449)    at com.sencha.gxt.widget.core.client.grid.ColumnHeader$Head.onBrowserEvent(ColumnHeader.java:396)    at com.google.gwt.user.client.DOM.dispatchEventImpl(DOM.java:1351)    at com.google.gwt.user.client.DOM.dispatchEvent(DOM.java:1307)    at sun.reflect.GeneratedMethodAccessor157.invoke(Unknown Source)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)    at java.lang.reflect.Method.invoke(Method.java:597)    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)    at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)    at com.google.gwt.core.client.impl.Impl.apply(Impl.java)    at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)    at sun.reflect.GeneratedMethodAccessor146.invoke(Unknown Source)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)    at java.lang.reflect.Method.invoke(Method.java:597)    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)    at java.lang.Thread.run(Thread.java:619

    I am using the code of the example in the Explorer dev demo, with my models and my DAO's.


    Any one else has this problem?


    Thank you.

  2. #2
    Ext GWT Premium Member icfantv's Avatar
    Join Date
    Sep 2011
    Location
    Superior, CO
    Posts
    411
    Vote Rating
    21
    icfantv will become famous soon enough icfantv will become famous soon enough

      0  

    Default


    I'm using RpcProxy with no trouble at all doing sorting.

    SortInfoBean doesn't throw an IllegalArgumentException. What are you doing on line 77 of PruebasRequestImpl.java?

    Note: the name of the sort field sent to the server in SortInfo is the name of the interface method you've defined in your implementation of the PropertyAccess<M> interface. If you've defined your own ValueProvider, then it will be the value returned by the getPath() method.

    When I ran into issues sorting, it was almost always centered around the sort field not getting passed to SQL correctly or the SQL data type of the field on which you are sorting (number vs. string).

    From the demos (Live Grid and Remote Filter Grid:

    Code:
    RpcProxy<PagingLoadConfig, PagingLoadResult<M>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<M>>() {  @Override
      public void load(PagingLoadConfig loadConfig, AsyncCallback<PagingLoadResult<M>> callback) {
        YOUR_GWT_SERVICE.YOUR_GWT_SERVICE_METHOD(loadConfig, callback);
      }
    };
    
    *snip*
    
    final PagingLoader<PagingLoadConfig, PagingLoadResult<M>> gridLoader = new PagingLoader<PagingLoadConfig, PagingLoadResult<M>>(proxy);
    gridLoader.setRemoteSort(true);
    
    *snip*
    
    Grid<Post> view = new Grid<M>(store, cm) {
      @Override
      protected void onAfterFirstAttach() {
        super.onAfterFirstAttach();
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
          @Override
          public void execute() {
            gridLoader.load();
          }
        });
      }
    };
    
    
    view.setLoadMask(true);
    view.setLoader(gridLoader);
    HTH,

    --adam

  3. #3
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    From parts of liondev's post, it appears that RequestFactory is being used instead of RPC. An except of the exception, formatted so it can be read slightly more easily:

    Code:
    java.lang.IllegalArgumentException: com.sencha.gxt.data.shared.SortInfoBean
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.checkStreamsNotCrossed(AbstractRequestContext.java:972)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.editProxy(AbstractRequestContext.java:509)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.edit(AbstractRequestContext.java:502)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.retainArg(AbstractRequestContext.java:1230)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.retainArg(AbstractRequestContext.java:1226)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.access$2(AbstractRequestContext.java:1223)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$StandardPayloadDialect.addInvocation(AbstractRequestContext.java:289)
        at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext.addInvocation(AbstractRequestContext.java:661)
        at mx.com.liondev.pruebas.client.RequestFactory.PruebasRequestImpl.getEmployees(PruebasRequestImpl.java:77)
        at mx.com.liondev.pruebas.client.Main$1.load(Main.java:108)
        at mx.com.liondev.pruebas.client.Main$1.load(Main.java:1)
        at com.sencha.gxt.data.shared.loader.RequestFactoryProxy.load(RequestFactoryProxy.java:24)
        at com.sencha.gxt.data.shared.loader.Loader.loadData(Loader.java:235)
        at com.sencha.gxt.data.shared.loader.Loader.load(Loader.java:183)
        at com.sencha.gxt.data.shared.loader.Loader.load(Loader.java:168)
        at com.sencha.gxt.widget.core.client.grid.GridView.doSort(GridView.java:1357)
        at com.sencha.gxt.widget.core.client.grid.GridView.onHeaderClick(GridView.java:2129)
        at com.sencha.gxt.widget.core.client.grid.GridView$7.onHeaderClick(GridView.java:1721)
        at com.sencha.gxt.widget.core.client.grid.ColumnHeader$Head.onClick(ColumnHeader.java:449)
        at com.sencha.gxt.widget.core.client.grid.ColumnHeader$Head.onBrowserEvent(ColumnHeader.java:396)
    The user has clicked on a column, which has caused the RequestContext to do some internal bookkeeping - the error is happening in AbstractRequestContext, the top frame in the stack trace:

    Code:
      private <T> AutoBean<T> checkStreamsNotCrossed(T object) {
        AutoBean<T> bean = AutoBeanUtils.getAutoBean(object);
        if (bean == null) {
          // Unexpected; some kind of foreign implementation?
          throw new IllegalArgumentException(object.getClass().getName());
        }
    RequestFactory can only handle interface objects that act as a proxy to a server type - this is why all objects used as long configs in GXT are just interfaces, with simple beans provided for use in cases where RequestFactory isn't being used. Our own example of this has sorting done locally, so we don't explain how to replace Bean impls with RF created impls.

    Most other load config objects can be replaced - this one might be missing a piece yet. I'll file an issue to see if there is a reasonable way to make this easier to work with, but in the meantime, take a look at your own Main:108, where you have a subclass of RequestFactoryProxy - iterate through the load config instances, and replace them with RequestFactory created models. These can be created through calling RequestContext.create(SortInfo.class) - this must be the same request context that you fire in that method.

  4. #4
    Sencha User
    Join Date
    Apr 2011
    Posts
    40
    Vote Rating
    1
    liondev is on a distinguished road

      0  

    Default


    Hi Colin Alworth

    The solution that you proposed works well (The default implementation with just GWT with a List of ValueProxys and sort info inside them). But would be nice if we can use as the 2.5.x RPC.

    Thank you.

  5. #5
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    I've filed an issue to look into what changes this would require, and will update this thread if/when we make changes to directly support this.

  6. #6
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    I've spent a little time fighting this this week, and wanted to share details about the problem, and some possible solutions, and hopefully get some feedback from people using this code to see what options we'd like to pursue.

    The basic issue, as you may be aware, is that RequestFactory must treat all objects as if they are just proxies for a 'real' object, so anything more complex than a string (or enum, or primitive, or date, or a collection) that gets run over the wire must have two parts - object, and proxy. RequestFactory isn't the only game in town though, so our load config and result objects need to work with RPC and regular AutoBeans as well. To that end, we define interfaces for all configs and results, as well as default implementations as POJO beans.

    Load results are fairly easy to deal with - define the data in such a way that RequestFactory/AutoBeans/RPC are able to generate objects using their own internal mechanisms (for RF isn't perfect, see http://code.google.com/p/google-web-...detail?id=6967). For those mechanisms to accept your load config objects and send them to the server is a different story, and that is what this thread is about. For RPC, you just need a proper POJO that can be shared by both the client and the server, for AutoBeans, an interface is sufficient (and it is fairly straightfoward to write code that iterates over POJO implementations of those interfaces to build AutoBean implementations, see the AutoBeanWriter class). But for RequestFactory, we need to understand what it is that makes RF different from RPC to see why this is difficult.

    When a request is made to the server, there are three basic steps. First, collect all of the domain objects present in the request to create or retrieve - ValueProxys are always created new, and EntityProxys are retrieved if they already existed or created if not. Second, all setters are called on them - if the object already existed, then only changed properties were sent, otherwise all were sent. And finally, the invocations made to service classes or to domain object instance methods are made. To make that request then, the client must specify all of the objects it will create, all of the setters to be applied to each one, and all of the service invocations to be made. All of these must go in the same request, as spreading the setters across multiple requests would mean that some changes might be made now, and some later. In the end this means that any new objects or modified objects must be manipulated with a single request, so all of those changes will make it to the server together.

    For the middle step, the value passed in for all of those setters must be translated from a proxy (client) to a domain (server) object. As mentioned earlier, Strings, primitives, Dates, enums undergo no changes, and collections (only List and Set are currently supported) are just iterated over, no other properties are read. So when we change a load config proxy into a load config domain object, all of the nested objects must be changed as well.

    The initial idea had been to make all of these load config and result interfaces implement ValueProxy (which is just a marker interface) and map them to their bean implementations, but the issue being discussed in this thread is where this broke down. SortInfo is a @ProxyFor SortInfoBean, so RF knows how to turn a SortInfo object on the client into a SortInfoBean on the server, but the issue is creating that initial SortInfo object so that it fits in the request. Usually, this looks something like this:

    Code:
    MyRequestFactory rf = ...//something that creates, inits the requestFactory
    MyRequestContext req = rf.myRequest();// create a request that we will send later
    
    SortInfo sort = req.create(SortInfo.class);// create a SortInfo that the request knows about
    sort.setSortDir(SortDir.ASC);// modify the properties, the req will track these changes
    sort.setSortField("name");
    
    req.loadMore(0,10,sort);// make an invocation to run on the server
    req.fire();// fire the request.
    So how do GXT widgets create these SortInfo instances so that they are made out of the correct RequestContext? So far, SortInfoBeans are created only in GridView and GroupingView, for sorting and grouping grids. This creation could be abstracted out, and we could support overriding this method (A). The main concern I have here is that now your view needs to know about the RequestContext, which can get a little messy. The other option would be for the RequestFactoryProxy to translate all incoming SortInfo instances into specific instances managed by the request about to be made (B).

    Option A looks like this in your code:
    Code:
    GridView<MyModel> gridView = new GridView<MyModel>() {
      @Override
      protected SortInfo createSortInfo() {
        // where currentRequest is the _next_ RF request to be fired to load items
        return currentRequest.create(SortInfo.class);
      }
    };
    And option B (based on the RequestFactory Grid):
    Code:
    RequestFactoryProxy<PagingLoadConfig, PagingLoadResult<PostProxy>> proxy = new RequestFactoryProxy<PagingLoadConfig, PagingLoadResult<PostProxy>>() {
      @Override
      public void load(PagingLoadConfig loadConfig, Receiver<? super PagingLoadResult<PostProxy>> receiver) {
        PostRequest req = rf.post();
        List<SortInfo> sortInfo = new ArrayList<SortInfo>();
        for (SortInfo orig : loadConfig.getSortInfo()) {
          SortInfo rfSortInfo = req.create(SortInfo.class);
          rfSortInfo.setSortDir(orig.getSortDir());
          rfSortInfo.setSortField(orig.getSortField());
          sortInfo.add(rfSortInfo);
        }
        req.getPosts(loadConfig.getOffset(), loadConfig.getLimit(), sortInfo).to(receiver);
        req.fire();
      }
    };
    This is a little wordy, but has the advantage that it should work with GXT as is, no changes required. It also wouldn't be too hard to abstract out - RequestFactoryProxy could have a method like this:
    Code:
    protected List<SortInfo> convertToRequestObjects(List<SortInfo> originalSortInfo, RequestContext request);
    which would wrap that loop.

    I'm personally in favor of B, but I am putting this out for discussion, especially if anyone has come across a third option in the course of their development efforts.

  7. #7
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    I haven't heard from any of the other participants in this thread, so I've made a change that can still be discussed, but this is what we are going with for now:

    RequestFactoryProxy:
    Code:
    ...
      /**
       * Helper method to translate a list of {@link SortInfo} instances to something that 
       * RequestFactory is able to send over the wire. Must be given the {@code RequestContext} 
       * instance to be used to send the request so the newly created object exists in the request.
       * 
       * @param request the request over which these items will be sent
       * @param original the list of {@code SortInfo} instances to copy
       * @return a list of {@code SortInfo} instances able to be sent over the given request
       */
      protected List<SortInfo> createRequestSortInfo(RequestContext request, List<? extends SortInfo> original) {
        List<SortInfo> sortInfo = new ArrayList<SortInfo>();
        
        for (int i = 0; i < original.size(); i++) {
          SortInfo originalSortInfo = original.get(i);
          SortInfo reqSortInfo = request.create(SortInfo.class);
          reqSortInfo.setSortDir(originalSortInfo.getSortDir());
          reqSortInfo.setSortField(originalSortInfo.getSortField());
          sortInfo.add(reqSortInfo);
        }
        
        return sortInfo;
      }
    This is in SVN and will be available in the next release, and an example of this will be available at http://staging.sencha.com:8080/examp...estfactorygrid shortly.

  8. #8
    Sencha User
    Join Date
    Jul 2009
    Posts
    24
    Vote Rating
    0
    bbg is on a distinguished road

      0  

    Default


    I use something like mentioned B-method for a long time. Just made several subclasses of ListLoadConfig for different purposes without any troubles.

  9. #9
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,640
    Vote Rating
    80
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    Ext GWT 3.0.0 RC2 has this helper method in RequestFactoryProxy - an example can be found now at http://www.sencha.com/examples-dev/#...estfactorygrid - all sorting is now remote, using this new helper method.

  10. #10
    Sencha User
    Join Date
    Apr 2011
    Posts
    40
    Vote Rating
    1
    liondev is on a distinguished road

      0  

    Default It works now.

    It works now.


    What about FilterConfig? like the gxt 2.5 (FilterPagingLoadConfig)

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar