问题
Here's my set-up:
In my XPage, I have an embedded view which opens a document in the adjacent Panel.
Clicking the doc link in the view sets the doc's UNID in a viewScope variable, and refreshes the Panel. The UNID variable is used to define the Page's Data Source Document (doc
).
Now in a Button, I want to get a handle to the next document in the view, but when the following SSJS code is run an error occurs at the last line:
var v:NotesView = database.getView("ViewByYear");
var curDoc:NotesDocument = doc.getDocument();
// curDoc = v.getFirstDocument(); /* if this line is uncommented the error does not occur */
if (curDoc==null) return(false);
var nextDoc = v.getNextDocument(curDoc);
The error message is: Script interpreter error, line=11, col=32: [TypeError] Exception occurred calling method NotesView.getNextDocument(lotus.domino.local.Document) null
if I uncomment the commented line (setting curDoc as the first document in the view), the error does not occur.
Any idea why this is happening? How is the document generated from the Data Source different? This document comes anyway from this same view which is embedded on the same XPage.
Thanks for your insights
回答1:
Actually, this works exactly as expected :-)
It has nothing to do with type of variables etc. Basically, if you want to traverse a view you need to set the "starting" point which in your case you do with curDoc = v.getFirstDocument();
. Then when you want the next document you use nextDoc = v.getNextDocument(curDoc);
, i.e. you tell it to return the document following the curDoc. This is the way the backend objects have been working since LotusScript was introduced back in version 4. And it is the same pattern no matter whether you use LotusScript, SSJS or Java :-)
So a common pattern would be:
var v:NotesView = database.getView("ViewByYear");
var curDoc = v.getFirstDocument();
while(null != curDoc){
// Do some work with curDoc
curDoc = v.getNextDocument(curDoc);
}
Now, you may have heard of memory considerations in relation to traversing a view. Basically, Domino will normally take care of memory handling for you. But especially when iterating over large document collections you should use a slightly different pattern (which you can also use for small document collections):
var v:NotesView = database.getView("ViewByYear");
var curDoc = v.getFirstDocument();
var nextDoc = null;
while(null != curDoc){
nextDoc = v.getNextDocument(curDoc);
// Do some work with curDoc
curDoc = null; // reclaim memory
curDoc = nextDoc;
}
/John
回答2:
The question has been answered and just wanted to add the recycle bit and I'm sure others can benefit it.
var v:NotesView = database.getView("ViewByYear");
//var curDoc:NotesDocument = doc.getDocument(); // not needed
var curDoc:NotesDocument = v.getFirstDocument(); // starting reference as explained by @John
while (curDoc != null){
var nextDoc = curDoc.getNextDocument(curDoc); // to fetch the next document
curDoc.recycle(); // recycle called to manage memory
curDoc = nextDoc; // replacing/passing data between variables
}
回答3:
I've modified my answer to utilize NotesViewNavigator:
var v:NotesView = database.getView("ViewByYear");
var curDoc:NotesDocument = doc.getDocument();
// curDoc = v.getFirstDocument(); /* if this line is uncommented the error does not occur */
if (curDoc==null) return(false);
var nav:NotesViewNavigator = v.createViewNavFrom(curDoc);
var entry:NotesViewEntry = nav.getNext();
if (entry == null) { return false; } // check to see if curDoc is last doc in view
var nextDoc:NotesDocument = entry.getDocument();
Is it possible curDoc is the last doc in the view in your code?
来源:https://stackoverflow.com/questions/32446515/xpages-typeerror-exception-at-view-getnextdocumentcurdoc