Announcement

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

    ListGrid invalidateCache()

    I'm using SmartGWT 2.2.

    I'm having some trouble with the ListGrid.invalidateCache() method. The situation is that I have a ListGrid that I populate with data, all good. At a certain point, I want to refresh that list, forcing a re-read from the database. After the re-read is completed, I want to take some action (ie., selecting a record, disabling some other controls, etc.).

    As far as I know, there are two possible approaches:

    Code:
    invalidateCache()
    This will empty the cached ResultSet, and do a new fetch from the database. Great, this works - but it has no callback, so I can't take any action on the completion of the fetch.

    The second approach is:

    Code:
    setData((RecordList)null);
    fetchData(new Criteria(), new FetchCallBack());
    This approach has a callback...but it's not working. I can see (from response times) that despite the setData((RecordList)null), the data set isn't really getting emptied, because the fetchData isn't going to the database. And the callback is never invoked (presumably because it's not going to the database?).

    Am I doing something obvious wrong?

    Thanks for any help.

    #2
    setData() to an empty Array or List, not null.

    Note the DataArrived event is another way to get notifications.

    Comment


      #3
      Thank you, using setData(new RecordList()) worked fine :)

      Comment


        #4
        I agree -- it seems most intuitive to provide a callback param for invalidateCache, especially to reselect the selected row after a refresh.

        Are there reasons this isn't the case? Can this API change be requested?

        Comment


          #5
          invalidateCache() does not imply a new fetch if the component is not drawn, does not have a ResultSet, and in various other circumstances.

          Comment


            #6
            Originally posted by Isomorphic
            Note the DataArrived event is another way to get notifications.
            I believe I tried tapping into the DataArrived event. But from my best recollection, it failed because the grid has not rendered any data rows yet (the data has just "arrived"), so it is not possible to select a row. But I could be wrong.

            Comment


              #7
              Selecting from DataArrived works.

              Comment


                #8
                My difficulty with DataArrived seems to be tracking the selected record before the grid gets refreshed with invalidateCache, and then referencing it inside DataArrived.

                I currently have an object-scope variable
                Code:
                private Record selectedPolicyRecord;
                that gets reassigned on every record click. However, it is null inside of the grid's DataArrived handler. (??) Perhaps that is because the variable is not final. But if I set it to final, I cannot reassign it when a new record gets clicked.

                I tried
                Code:
                invalidateCache()
                and
                Code:
                setData(new Record[0])
                fetchData(new Criteria())
                But nothing seems to be working quite right. :(

                So here's my goal: use a button to refresh a grid, keeping its row selected (if it still exists). How would you suggest writing the onClick, FetchData, and/or DataArrived methods for this?

                Comment


                  #9
                  Can't comment on your confusion with Java scoping, but, the Record is not necessarily the same Record if a new fetch has been performed. You should find the new Record by primary key.

                  Comment


                    #10
                    I'm about to give up, but want to give it one more shot. Here is my code:

                    Code:
                    refreshButton.addClickHandler(new ClickHandler() {
                    	public void onClick(ClickEvent event) {
                    		final Record sr = policySummaryGrid.getSelectedRecord();
                    		policySummaryGrid.setData(new Record[0]);
                    		policySummaryGrid.fetchData(new Criteria(), new DSCallback() {
                    			public void execute(DSResponse response, Object rawData, DSRequest request) {
                    				Window.alert(""+policySummaryGrid.getDataAsRecordList().getLength());
                    				if (sr != null) {
                    					Window.alert(""+sr.getAttributeAsInt("alert_policy_id"));
                    					ListGridRecord selectRecord = new ListGridRecord();
                    					selectRecord.setAttribute("alert_policy_id", sr.getAttributeAsInt("alert_policy_id"));
                    					policySummaryGrid.selectRecord(selectRecord);
                    					policySummaryGrid.markForRedraw(); // makes no difference
                    				}
                    			}
                    		});
                    	}
                    });
                    Now,
                    Code:
                    Window.alert(""+policySummaryGrid.getDataAsRecordList().getLength());
                    properly sees the number of records in the grid.
                    Code:
                    Window.alert(""+sr.getAttributeAsInt("alert_policy_id"));
                    properly sees the id. So... why isn't the record being selected in the grid? Any ideas?
                    Last edited by bootz15; 18 May 2011, 06:38.

                    Comment


                      #11
                      You created a record using new ListGridRecord(). It's not in the grid's data.

                      We're not sure what to do about your expectation that either this or your previous attempt would work (you're making assumptions about object identity or implicit lookups that aren't doc'd, and we're not sure where to put doc to correct this notion) but there are a huge number of find() utility methods on ResultSet to locate loaded Records - the correct code is just grid.getResultSet().find(pkField, pkValue).

                      Comment


                        #12
                        Wow, I finally got it!

                        Code:
                        refreshButton.addClickHandler(new ClickHandler() {
                        	public void onClick(ClickEvent event) {
                        		final Record sr = policySummaryGrid.getSelectedRecord();
                        		policySummaryGrid.setData(new Record[0]);
                        		policySummaryGrid.fetchData(new Criteria(), new DSCallback() {
                        			public void execute(DSResponse response, Object rawData, DSRequest request) {
                        				if (sr != null) {
                        					ListGridRecord selectRecord = new ListGridRecord();
                        					ListGridRecord[] lgrs = policySummaryGrid.getRecords();
                        					for (ListGridRecord lgr : lgrs) {
                        						if (lgr.getAttributeAsInt("alert_policy_id") == sr.getAttributeAsInt("alert_policy_id")) {
                        							selectRecord = lgr; // found it!
                        						}
                        					}
                        					policySummaryGrid.selectRecord(selectRecord);
                        					policySummaryGrid.markForRedraw();
                        				}
                        			}
                        		});
                        	}
                        });
                        Can't say it's the most intuitive code.... seems like way too much boiler plate code for a very common Ajax scenario. I'm mildly disappointed, but at least it works now..

                        Comment


                          #13
                          I guess Isomporphic tried to say the following:

                          1. In your code you store the selected Record tp a local variable
                          Code:
                          final Record sr = policySummaryGrid.getSelectedRecord();
                          2. Then you do your fetch and handle the response in a callback.

                          3. Finally you try to select the initially selected record with
                          Code:
                          policySummaryGrid.selectRecord(selectRecord);
                          When you reselect the record in step 3 the record instance representing the selected row is not necessarily the same Record instance that was selected in step 1.

                          What you should do is not to store the Record, but just its primary and select that via grid.getResultSet().find.

                          BTW: sr has to be final, otherwise you can't use it in your anonymous inner Callback class. The only way for sr not to be final is to declare it a member variable

                          Comment


                            #14
                            That's good to know about the grid.getResultSet().find() method. This turns my code to:

                            Code:
                            refreshButton.addClickHandler(new ClickHandler() {
                            	public void onClick(ClickEvent event) {
                            		final Record sr = policySummaryGrid.getSelectedRecord();
                            		policySummaryGrid.setData(new Record[0]);
                            		policySummaryGrid.fetchData(new Criteria(), new DSCallback() {
                            			public void execute(DSResponse response, Object rawData, DSRequest request) {
                            				if (sr != null) {
                            					Record select = policySummaryGrid.getResultSet().find("alert_policy_id", sr.getAttributeAsInt("alert_policy_id"));
                            					policySummaryGrid.selectRecord(select);
                            				}
                            			}
                            		});
                            	}
                            });
                            That is looking better now, at least for Java ;) Ideally, I would like to see and API like
                            Code:
                            fetchData(Criteria c, Record selectAfterFetch)
                            Very intuitive :)

                            Comment


                              #15
                              Originally posted by msturzen
                              BTW: sr has to be final, otherwise you can't use it in your anonymous inner Callback class. The only way for sr not to be final is to declare it a member variable
                              Thanks msturzen. I was having tricky scoping problems because sometimes policySummaryGrid.getSelectedRecord() was returning null (when nothing selected), so I had to test that before calling .getAttribute() on the record to set the id Integer.

                              Thus the id Integer could not be final (to allow conditional setting), but then it needed to be final (to be used in the callback). Altogether it seemed like a catch22. So instead, I just stored the final record and tested it inside the callback.
                              Last edited by bootz15; 18 May 2011, 07:38.

                              Comment

                              Working...
                              X