📄 resultset.js
字号:
// Criteria// --------------------------------------------------------------------------------------------//> @method resultSet.setCriteria()// Set the filter criteria to use when fetching rows.// <P>// Setting new criteria will invalidate the current cache, if any.//// @param newCriteria (Criteria) the filter criteria// @visibility external//<// An overview on the caching system:// We have 2 kinds of cache// - the cache of results that matches the current criteria: this.localData// - the cache of every record we've been handed by the server: this.allRows// * When in local filtering mode, this.allRows is always the entire set of records in the// data-set, and all sorting and filtering is local (modifying this.localData)// * When in basic filtering mode, we also always populate both caches.// On the first fetch we both caches with the results returned from the server.// On subsequent changes to filter criteria, we will either do a client-only filter and // modify the local cache, or perform a new server fetch and update both caches depending// on useClientFiltering and whether the new critia are more or less restrictive// * In paged mode, when we retrieve data from the server, if it is an incomplete data set, // records will be slotted into the local cache. Once we have retrieved all matching records// for a set of criteria, these will be stored as this.allRows, and for subsequent fetches// we'll filter on the client and modify the local cache only if possible (similar to // "basic" mode).// Note: If the user changes textMatchStyle it can become more restrictive // (EG from substring to exact match). In this case we can avoid hitting the server, and // perform a local filter. Note that if this happens the allRows cache will contain more rows// than it would for the same "allRowsCriteria" with the new text match style, but we always// apply a local filter to this data so the developer / user should never see these extra rows.setCriteria : function (newCriteria) { // NOTE: determine this before setting new criteria, otherwise, if we a full cache for the // current criteria, and we just changed to empty criteria, we'll believe we have a full // cache for empty criteria, hence all rows cached var allRowsCached = this.allRowsCached(); // remember whether criteria are empty this._emptyCriteria = (isc.getKeys(newCriteria).length == 0); var oldCriteria = this.criteria, oldTextMatchStyle = this._textMatchStyle; this.criteria = newCriteria; this._textMatchStyle = this.context ? this.context.textMatchStyle : null; // If the textMatchStyle has changed, we may have to hit the server even if the // new criteria are more restrictive or unchanged. var result = this.compareTextMatchStyle(this._textMatchStyle, oldTextMatchStyle); // If text match style has become less restrictive, it doesn't matter whether the criteria // are more restrictive or unchanged - we are likely to have to hit the server for fresh // data if (result >= 0) { // if we have switched into local filtering mode after obtaining a full cache (indicated by // allRowsCriteria being set), check whether the new criteria are more of less restrictive // than the criteria in use when we obtained a full cache. This determines whether we can // continue to do local filtering. var criteriaResult = this.compareCriteria(newCriteria, this.allRowsCriteria ? this.allRowsCriteria : oldCriteria, this.context); // If the criteria changed, respect whether they are more or less strict // Otherwise use the result based on whether the text match style changed (becoming more // or less strict). if (criteriaResult != 0) result = criteriaResult; } if (result == -1) { // criteria less restrictive if (this.isLocal() || (!this.allRowsCriteria && this.allRows && this.shouldUseClientFiltering())) { // derive localData from the set of all rows if (this.allRows != null) this.filterLocalData(); } else { //>DEBUG this.logInfo("setCriteria: filter criteria changed, invalidating cache"); //<DEBUG this.invalidateCache(); this.allRowsCriteria = null; delete this._emptyAllRowsCriteria; } return true; } else if (result == 1) { // criteria more restrictive. If we are allowed to useClientFiltering and we have a // complete cache for the current criteria, use client-side filtering from here on, // until the criteria become less restrictive than the allRowsCriteria. if (this.allRowsCriteria) { // if allRowsCriteria is set, it indicates we have already started using // client-side filtering this.filterLocalData(); } else if (this.shouldUseClientFiltering() && this.allMatchingRowsCached()) { // begin using client-side filtering this.allRows = this.localData; this.allRowsCriteria = oldCriteria; this._emptyAllRowsCriteria = (isc.getKeys(oldCriteria).length == 0); this.filterLocalData(); } else { // can't use client-side filtering, just invalidateCache //>DEBUG this.logInfo("setCriteria: filter criteria changed, invalidating cache"); //<DEBUG this.invalidateCache(); } return true; } else { // result = 0, identical criteria. // When we are using local filtering after obtaining a full cache (allRowsCriteria != // null), this means the new criteria are identical to the criteria at the time we // switched into local filtering mode (allRowsCriteria). We still need to perform // local filtering in case we *were* using criteria more restrictive than allRowsCriteria // and just switched back to the allRowsCriteria. if (this.allRowsCriteria && this.compareCriteria(newCriteria, oldCriteria) != 0) { this.filterLocalData(); } } //>DEBUG this.logInfo("setCriteria: filter criteria unchanged"); //<DEBUG return false;},//>!BackCompat 2004.7.23setFilter : function (newCriteria) { return this.setCriteria(newCriteria) },//<!BackCompat//> @method resultSet.getCriteria()// Get the current criteria for this ResultSet.// @return (Criteria) current criteria// @visibility external//<getCriteria : function () { return this.criteria },//> @method resultSet.compareCriteria()// Default behavior is to call +link{dataSource.compareCriteria()} to determine whether new// criteria is guaranteed more restrictive, equivalent to the old criteria, or not guaranteed// more restrictive, returning 1, 0 or -1 respectively.// <P>// Override this method or +link{dataSource.compareCriteria()} to implement your own client-side// filtering behavior.//// @param newCriteria (Criteria) new filter criteria// @param oldCriteria (Criteria) old filter criteria// @param [requestProperties] (DSRequest Properties) dataSource request properties// @param [policy] (string) overrides +link{criteriaPolicy}// @return (Number) 0 if the filters are equivalent, 1 if newFilter is guaranteed more// restrictive, and -1 if newFilter is not guaranteed more restrictive// @see criteriaPolicy// @visibility external//<compareCriteria : function (newCriteria, oldCriteria, requestProperties, policy) { return this.getDataSource().compareCriteria( newCriteria, oldCriteria, requestProperties ? requestProperties : this.context, policy ? policy : this.criteriaPolicy);},compareTextMatchStyle : function (newStyle, oldStyle) { return this.getDataSource().compareTextMatchStyle(newStyle, oldStyle);},//> @method resultSet.willFetchData()// Will changing the criteria for this resultSet require fetching new data from the server, // or can the new criteria be satisfied from data already cached on the client?<br>// Second <code>textMatchStyle</code> parameter determines whether a change of text-match style// will require a server fetch - for example if filter is being changed between// an exact match (from e.g: +link{ListGrid.fetchData()}) and a substring match // (from e.g: +link{ListGrid.filterData()}).<br>// This method can be used to determine whether +link{ListGrid.fetchData()} or // +link{ListGrid.filterData()} would cause a server side fetch when passed a certain set of // criteria.// @param newCriteria (Criteria) new criteria to test.// @param [textMatchStyle] (String) New text match style. If not passed assumes // textMatchStyle will not be modified.// @return (boolean) true if server fetch would be required to satisfy new criteria.// @visibility external//<willFetchData : function (newCriteria, textMatchStyle) { var result; if (textMatchStyle != null) { result = this.compareTextMatchStyle(textMatchStyle, this._textMatchStyle); if (result == -1) return true; } var oldCriteria = this.allRowsCached() ? this.allRowsCriteria : this.criteria; result = this.compareCriteria(newCriteria, oldCriteria); // If we have no change in criteria we won't perform a fetch if (result == 0) return false; // If we can't filter on the client we always perform a true fetch if (!this.shouldUseClientFiltering()) return true; // If we don't have a full cache of rows matching the current criteria, we perform a true // fetch if (!this.allMatchingRowsCached()) return true; // criteria are less restrictive => fetch return (result == -1);}, // Sorting// --------------------------------------------------------------------------------------------//> @method resultSet.sortByProperty()// Sort this ResultSet by a property of each record.// <P>// Sorting is performed on the client for a ResultSet that has a full cache for the current// filter criteria. Otherwise, sorting is performed by the server, and changing the sort order// will invalidate the cache.// <P>// <b>NOTE:</b> normalizers are not supported by ResultSets in "paged" mode, although valueMaps// in the DataSource are respected by the SQLDataSource.//// @include List.sortByProperty()// @visibility external//<sortByProperty : function (property, sortDirection, normalizer, context) { // If we were passed a null normalizer - use the field type as normalizer instead. // (May still be null, in which case array sorting will try to derive from actual elements) if (normalizer == null) { var field = this.getDataSource().getField(property); if (field) normalizer = field.type; } // If we're already sorted as appropriate, no-op. if (this._sortProperty == property && this._sortDirection == sortDirection && this._normalizer == normalizer) return; // remember sort and direction this._sortProperty = property; this._sortDirection = sortDirection; this._normalizer = normalizer; this._sortContext = context; // set sortBy for any subsequent fetches. // - if client sorting has been disabled, the server must sort for us // - if we are using paging, the server must sort for us, since server and client sort may // not agree // - XXX we could conditionally turn this off in situations where the cache is going to // be completed when the next set of rows arrives, assuming the cache doesn't get // invalidated if (this.isPaged() || !this.shouldUseClientSorting()) { this._serverSortBy = (this._sortDirection ? "" : "-") + this._sortProperty; } this._doSort();},//> @method resultSet.unsort() (A)// Turn sorting off for this result set, indicating that the current sort// order should be preserved. Return true if this is supported in this List.// <P>// Some implementations may not support this -- they should return false// to indicate to the caller that sort order must be maintained (eg: in// the case where sort order is derived from the server, etc).//// @group sorting//// @return (boolean) true == list supports unsorting, false == not supported.//<unsort : function () { if (!this.allMatchingRowsCached()) return false; // stop maintaining the sort order this._sortProperty = null; // unsort the cache Array or it will continue to apply the last sort order to rows added // without a specific index if (this.localData) this.localData.unsort(); return true;},// for internal callers - sort by current sort property_doSort : function () { var property = this._sortProperty, up = this._sortDirection; // if we don't have data yet, wait to be asked for data. // if we have no sort property, leave dataset in current order if (this.localData == null || property == null) return; // we can sort locally if we have the entire result set *for the current filter* cached if (this.canSortOnClient()) { //>DEBUG this.logInfo("sortByProperty(" + property + ", " + up + "): full cache allows local sort"); //<DEBUG // if we have data, and a sort order, sort it. Otherwise wait until we have data // and/or a sort order. if (property != null) { // XXX NOTE: function-based normalizers are not supported by server sort (and can't // be). valueMap-based normalizers are, but currently are not submitted, so only // valueMaps defined on server DataSources work. this.localData.sortByProperty(property, up, this._no
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -