📄 resulttree.js
字号:
// Fire any callback passed to 'loadChildren' in the scope of this tree. if (context.childrenReplyCallback) { this.fireCallback(context.childrenReplyCallback, "node", [parentNode], this); } // NOTE: when paging within child sets is implemented, we'll add "startChild,endChild" to // this signature if (this.dataArrived != null) { isc.Func.replaceWithMethod(this, "dataArrived", "parentNode"); this.dataArrived(parentNode); }},// Cache sync// ------------------------------------// On initial load of data for some folder, we always retrieve the entire set of children for the// parents of the node.// When dataChanged fires on our dataSource, we need to update these stored children arrays to// incorporate the modified nodes into our tree of local data.// helper method to get this.dataSource as a datasource object (even if specified as an ID only)getDataSource : function () { return isc.DataSource.getDataSource(this.dataSource);},//> @method resultTree.invalidateCache() [A]// Manually invalidate this ResultTree's cache.// <P>// Generally a ResultTree will observe and incorporate updates to the DataSource that provides it's// records, but when this is not possible, <code>invalidateCache()</code> allows manual cache// invalidation.// <P>// Components bound to this ResultTree will typically re-request the currently visible portion// of the dataset, causing the ResultTree to re-fetch data from the server.// @visibility external//<invalidateCache : function () { if (!this.isLoaded(this.root)) return; // reset root to refetch all our data. this.setRoot(this.makeRoot());},dataSourceDataChanged : function (dsRequest, dsResponse) { // respsect the flag to suppress cache sync altogether if (this.disableCacheSync) return; var updateData = isc.DataSource.getUpdatedData(dsRequest, dsResponse, this.updateCacheFromRequest); this.handleUpdate(dsRequest.operationType, updateData, dsResponse.invalidateCache);},handleUpdate : function (operationType, updateData, forceCacheInvalidation) { if (isc._traceMarkers) arguments.__this = this; if (this.dropCacheOnUpdate || forceCacheInvalidation) { this.invalidateCache(); if (!this.getDataSource().canQueueRequests) this.dataChanged(); return; } // update our cached tree directly Note our cache is filtered, so we may just discard the // update if the new row doesn't pass the filter this.updateCache(operationType, updateData); this.dataChanged();},// updateCache() - catch-all method fired when the dataSource dataChanged method fires.// Integrates (or removes) the modified nodes into our local tree of data.updateCache : function (operationType, updateData) { if (updateData == null) return; operationType = isc.DS._getStandardOperationType(operationType); //>DEBUG if (this.logIsInfoEnabled()) { this.logInfo("Updating cache: operationType '" + operationType + "', " + updateData.length + " rows update data" + (this.logIsDebugEnabled() ? ":\n" + this.echoAll(updateData) : "")); } //<DEBUG switch (operationType) { case "remove": this.removeCacheData(updateData); break; case "add": this.addCacheData(updateData); break; case "replace": case "update": this.updateCacheData(updateData); break; }}, addCacheData : function (updateData) { if (!isc.isAn.Array(updateData)) updateData = [updateData]; // Don't add rows that don't pass filtering var validRows = this.getDataSource().applyFilter(updateData, this.criteria, this.context); var pk = this.getDataSource().getPrimaryKeyFieldNames()[0]; for (var i = 0; i < validRows.length; i++) { var parentNode = this.find(pk, validRows[i][this.parentIdField]); // Duplicate the node when adding it -- this is required to avoid us writing // properties onto the object directly // Note: add() will automatically sort the new node in the children array if (parentNode != null && (this.getLoadState(parentNode) == isc.Tree.LOADED)) this.add(isc.addProperties({}, validRows[i]), parentNode); }},updateCacheData : function (updateData) { if (!isc.isAn.Array(updateData)) updateData = [updateData]; //>DEBUG var removedRows = 0, addedRows = 0; //<DEBUG var pk = this.getDataSource().getPrimaryKeyFieldNames()[0]; for (var i = 0; i < updateData.length; i++) { var updateRow = updateData[i]; var matchesFilter = this.getDataSource().recordMatchesFilter(updateRow, this.criteria, this.context); //>DEBUG if (this.logIsDebugEnabled() && !matchesFilter) { this.logDebug("updated node :\n" + this.echo(updateRow) + "\ndidn't match filter: " + this.echo(this.criteria)); } //<DEBUG var node = this.find(pk, updateRow[pk]); // Very likely we'll see null nodes - we probably haven't opened their parent folder yet // However - check for the case where we have and if so, add to our data-set if (node == null) { if (matchesFilter) { var parentNode = this.find(this.parentIdField, updateRow[this.parentIdField]); if (parentNode && (this.getLoadState(parentNode) == isc.Tree.LOADED)) { this.logWarn("updated row returned by server doesn't match any cached row, " + " adding as new row. Primary key value: " + this.echo(updateRow[pk]) + ", complete row: " + this.echo(updateRow)); // duplicate the update row before integrating it into our dataSet updateRow = isc.addProperties({}, updateRow); this.add(parentNode, updateRow); } } continue; } if (matchesFilter) { // the change may have reparented a node. if (updateRow[this.parentIdField] != node[this.parentIdField]) { var newParentNode = this.find(pk, updateRow[this.parentIdField]); if (newParentNode == null || (this.getLoadState(newParentNode) != isc.Tree.LOADED)) { this.remove(node) removedRows ++; continue; } this.move(node, newParentNode); } // apply all modified fields to the node. isc.addProperties(node, updateRow); } else { this.remove(node); removedRows++; } } //>DEBUG if (this.logIsDebugEnabled()) { this.logDebug("updated cache, " + (updateData.length - removedRows) + " out of " + updateData.length + " rows remain in cache, " + addedRows + " row(s) added."); } //<DEBUG},removeCacheData : function (updateData) { if (!isc.isAn.Array(updateData)) updateData = [updateData]; var nodes = [], primaryKey = this.getDataSource().getPrimaryKeyFieldNames()[0]; for (var i = 0; i < updateData.length; i++) { // find the actual node object in the tree and remove it var node = this.find(primaryKey, updateData[i][primaryKey]); if (node == null) { this.logWarn("Cache synch: couldn't find deleted node:" + this.echo(updateData[i])); continue; } nodes.add(node); } this.removeList(nodes); },// get the title for this nodegetTitle : function (node) { // look up the node's DataSource and return its title field var dataSource = this.getNodeDataSource(node); // the special, singular root node has no DataSource if (!dataSource) return "root"; var title = node[dataSource.getTitleField()]; if (title != null) return title; // if there's no title on this node, try not to leave a blank return this.Super("getTitle", arguments);},// indexOf: As with ResultSets support being passed primaryKey values only as well as pointers // to nodes// Note: This will return the index wrt the visible (open) nodes of the tree. If the node is not// currently visible, -1 will be returned.indexOf : function (node, a,b,c,d) { var pks = this.getDataSource().getPrimaryKeyFieldNames(); for (var i = 0; i < pks.length; i++) { var pk = pks[i]; if (node[pk] != null) return this.findIndex(pk, node[pk]); } return this.invokeSuper(isc.ResultTree, "indexOf", node, a,b,c,d);}}); isc.ResultTree.registerStringMethods({ //> @method resultTree.dataArrived // This callback fires whenever the resultTree receives new nodes from the server, after // the new nodes have been integrated into the tree. // // @param parentNode (TreeNode) The parentNode for which children were just loaded // // @visibility external //< dataArrived: "parentNode"});
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -