Gelmiş geçmiş en büyük porno sitemiz olan 2pe de her zaman en kaliteli pornoları sunmayı hedefledik. Diğer video sitemiz olan vuam da ise hd porno ağırlıklı çalışmalara başladık.

  1. #1
    Ext GWT Premium Member
    Join Date
    Oct 2008
    Posts
    72
    Vote Rating
    5
    elirov is on a distinguished road

      2  

    Default Unanswered: Gxt3 - store.getModifiedRecords() not actually returning modified records

    Unanswered: Gxt3 - store.getModifiedRecords() not actually returning modified records


    It looks like the behavior of store.getModifiedRecords() changed between gxt2 and gxt3 in the following way:

    in gxt2, getModifiedRecords() returned a list of actual modified Record wrappers with Models that had changes already applied

    in gxt3, it returns a list of Record wrappers that had modifications but where the wrapped models do not show the actual modifications.

    So, we can't see the modified objects until we actually commit. That means that we need to commitChanges() first, THEN try to send the modified objects to the server to save them. However, that means that if the save fails, then we have unsaved changes in the grid reflected as committed changes.

    Here's the code. It doesn't actually save any changes on the first save() because store.getModifiedRecords() gives back the set of Models that were edited, but it gives them without the actual changes applied.

    Maybe we can get a store.getModifiedModels<T>() function that will return the actual models with their modifications.

    Collection<Store<RadarChartMeasure>.Record> modifiedRecords = store.getModifiedRecords();
    for (Record r : modifiedRecords) {
    RadarChartMeasure k = (RadarChartMeasure) r.getModel();
    data.remove(k); // data is a hashset that stores the data that we want to save in the server
    data.add(k);
    }
    final AutoProgressMessageBox waitBox = new AutoProgressMessageBox("Saving Data...");
    waitBox.show();
    Report.getService().saveProviderOpsStatData(request, new EGWTCallback<Void>() {
    @Override
    public void doOnFailure(Throwable e) {
    waitBox.hide();
    GWT.log("Could not save provider ops stats config", e);
    new MessageBox("Error", "Could not save provider ops stats config").show();
    }


    @Override
    public void onSuccess(Void result) {
    store.commitChanges(); //would be nice to commit AFTER the save was successful
    waitBox.hide();
    }
    });

  2. #2
    Sencha User
    Join Date
    Sep 2011
    Location
    Canada
    Posts
    19
    Vote Rating
    -1
    jtaekema is an unknown quantity at this point

      -1  

    Default


    Where X is your data type:
    Code:
    Collection<X> modified = new ArrayList<X>();
    for (Store<X>.Record record : store.getModifiedRecords()) {
      X model = record.getModel();
      for (Change<X, ?> change : record.getChanges()) {
         change.modify(model);
      }
      modified.add(model);
    }
    // now you can submit your modified models, and store.commitChanges() on success

  3. #3
    Ext GWT Premium Member
    Join Date
    Oct 2008
    Posts
    72
    Vote Rating
    5
    elirov is on a distinguished road

      0  

    Default


    Nice one. It would be great if there was a built-in method for this, though. Sencha?

  4. #4
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,717
    Answers
    109
    Vote Rating
    87
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    This is indeed different, but for good reason. In GXT 2, all model objects implemented the ModelData interface, which described exactly how they must store their data. In GXT 3, we allow for any POJO to be a model, and so remove many of the constraints that ModelData added, including:

    * Model setters need not exist - as long as a ValueProvider is defined that can make the changes, GXT can handle it.
    * If there is a setter, it can have side effects other than just setting a field - events could be fired, dirty flags can be set, whatever makes sense for the use case
    * Properties can be read-only, or write-only, and the ability to revert a value after it has been set relies on having the ability to read the original value

    Combining the first and third bullet point can be very helpful for RequestFactory - data can be just readonly getters, and a RequestContext can be used to apply the changes. But since RequestContexts can't have service calls removed once they are added, it is important not to add them until it is certain that these are the values to send to the server.

    By lifting these constraints, GXT 3 is more flexible, and is certain to work with all kinds of persistence tools and model objects. The solution jtaekema offers is essentially the same as actually committing the change, except it doesnt get rid of the record instance.

    Think of a Record not as a store the now-stale values, but as an intermediate step before actually modifying the models - changes are queued up on the Record, and only when you are ready to commit and clear the dirty flags do they actually pass through to the model. You can read these new values out without actually changing the model as in jtaekema's example, something like this:

    Code:
    for (Store<X>.Record record : store.getModifiedRecords()) {
      X model = record.getModel();
      for (Change<X, ?> change : record.getChanges()) {
         Object newValue = change.getValue();
         // do something with both model and newValue
      }
    }

  5. #5
    Ext GWT Premium Member
    Join Date
    Oct 2008
    Posts
    72
    Vote Rating
    5
    elirov is on a distinguished road

      0  

    Default


    Would it make sense to add this method to the ListStore class?

    public ArrayList<M> getEditedModels() {
    Collection<com.sencha.gxt.data.shared.Store<M>.Record> modifiedRecs = getModifiedRecords();
    ArrayList<M> modifiedModels = new ArrayList<M>();
    for (Record r : modifiedRecs) {
    r.commit(false);
    modifiedModels.add(r.getModel());
    }
    return modifiedModels;
    }

    This would return the modified models without actually committing the changes. This way, the save method could:
    1. getEditedModels() -> and then save them to the server
    2. onSuccess() -> listStore.commit() to hide the red tags

    Note, I'm using ArrayList on purpose instead of List in order to make it easier to pass the object properly through GWT's RPC mechanism without causing additional code bloat. I think the most common use-case for this method would be to pass data back to the server, so I think it makes sense in this case to use the concrete class.

  6. #6
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,717
    Answers
    109
    Vote Rating
    87
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    Actually, your code does commit the changes - r.commit(false) performs all changes, but just doesnt fire any events. This would not update the UI right away, but if the user were to filter or sort the items locally (among other things), the UI would need to completely repaint items, which would result in reading that there are no more changes locally.

    The easiest way I see to provide such a feature would be to first clone the original objects, then apply all Change objects in the Record to the clone, not to the original (for each Change c : Record.getChanges, c.modify(clone) more or less). Then, send the clones to the server instead of the originals. Of course, without full reflection on the client, or Store simply not functioning without all model objects implementing Clonable, this won't work. That said, you can still build this feature into a store subclass, or into another part of your application.

  7. #7
    Ext GWT Premium Member
    Join Date
    Oct 2008
    Posts
    72
    Vote Rating
    5
    elirov is on a distinguished road

      0  

    Default


    Oh. Duh.. There must be a way to get this done. I can't believe such a common use-case is so hard to do...

  8. #8
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,717
    Answers
    109
    Vote Rating
    87
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    Does my description with cloning not fit your case? This would be a minimal change in your model to allow reflection.

    Another idea, this would reduce the data sent over the wire:
    For each model, send its ID and all changes made. Each change consists of the property changed, and the value it was changed to (assumed to be serializable). The ID can be read from the model as you iterate through Records, the property name and value from the PropertyChange object (PropertyChange.getChangeTag returns a ValueProvider which has a getPath method to get the property - if you don't have a custom implementation of Change, this cast will always work). This would very nearly get you some of RequestFactory's sparse update features, usable from within RPC.

    We have to be somewhat careful when building 'supported features' like this so that they work with RPC, RequestFactory, and any other JSON/XML or other way to talk to the server - not every application out there uses the same mechanism, and we aim to be flexible enough to support any or all.

    Another idea: Actually perform the commit() operation, but before doing so, record the 'old' values by reading out the Change objects. This could let you revert to those old values if the server fails for some reason.

  9. #9
    Ext GWT Premium Member
    Join Date
    Oct 2008
    Posts
    72
    Vote Rating
    5
    elirov is on a distinguished road

      0  

    Default


    It might work, but it seems like a bit of a hack. Maybe there's a way for the store to do the commit/save old values strategy?

  10. #10
    Sencha User
    Join Date
    Jul 2011
    Posts
    92
    Vote Rating
    5
    Andreas Samjeske is on a distinguished road

      0  

    Default


    Quote Originally Posted by jtaekema View Post
    Where X is your data type:
    Code:
    Collection<X> modified = new ArrayList<X>();
    for (Store<X>.Record record : store.getModifiedRecords()) {
      X model = record.getModel();
      for (Change<X, ?> change : record.getChanges()) {
         change.modify(model);
      }
      modified.add(model);
    }
    // now you can submit your modified models, and store.commitChanges() on success
    Did anyone ever tried to run this code? Over here I get the following error on store.commitChanges():
    Code:
    java.lang.AssertionError: Current value was somehow stored in a record's change set!
        at com.sencha.gxt.data.shared.Store$Record.commit(Store.java:186)
        at com.sencha.gxt.data.shared.Store.commitChanges(Store.java:579)
    ...
    Seems like u shouldn't call
    Code:
    change.modify(model);
    on the actual model gotten of records.
    Fix: Make a copy of model and modify that one.