Results 1 to 2 of 2

Thread: Better implementation than my AggregatorStore?

  1. #1
    Sencha Premium User SebTardif's Avatar
    Join Date
    Feb 2011
    Location
    Cambridge, MA
    Posts
    1,294
    Answers
    16

    Default Better implementation than my AggregatorStore?

    This is more about sharing my code, than a question, but if you find mistake in my code please let me know.

    Mainly, they are so many issues with the grid grouping, and one of my use case works better, if I do the aggregation on the store, then show the aggregated value in a more flat grid.

    So that AggregatorStore below handle that nicely:

    Code:
    /*
      Aggregate data from another store. Will end-up with less rows, but with bigger numbers.
      Use fields declared in AggregatorStore to know which field to care about
    
    
    	store: 'StoreWithDateToAggregate',
    	groupField : 'day',
    	fields : [ {
    		name : 'cost',
    		type : 'int',
    		summaryFn : Ext.Array.sum
    	}, {
    		name : 'extraCosts',
    		mapping : 'superCosts', // match different name in store we depend on
    		summaryFn : Ext.Array.sum
    	} ]
     
     	// We have two asynchronous cases we try to handles while we may be called and both didn't yet happen.
     	// The binding of our dependent store may not have yet happened, happen often if it come from a viewmodel, the store will show up only after parameters available
     	// Then, while the store may be bind, it may still not have been loaded
     */
    Ext.define('Nextt.store.AggregatorStore', {
    	extend : 'Ext.data.Store',
    	uses : [ 'Nextt.Promise' ],
    	mixins : [ 'Ext.util.StoreHolder' ],
    	config : {
    		store : null
    	},
    	constructor : function(config) {
    		this.callParent(arguments);
    
    
    		this.initConfig(config);
    	},
    	setStore : function(store) {
    		this.bindStore(store);
    	},
    	onBindStore : function(store, initial) {
    		this.initialLoad();
    	},
    	initialTranslateDoneDeferred : new Ext.Deferred(),
    	initialLoad : function() {
    		var me = this;
    		// maybe called more than one time, but should do something only when store is ready
    		if (me.getCount() > 0) {
    			// already done
    			return;
    		}
    		var promiseStoreLoaded = Nextt.Promise.getPromiseStoreLoaded(me.getStore());
    		Ext.promise.Promise.all(promiseStoreLoaded).then(function(values) {
    			me.translateAll();
    			me.initialTranslateDoneDeferred.resolve();
    		});
    		me.getStore().on({
    			update : me.onUpdate,
    			scope : me
    		});
    	},
    	onUpdate : function(store, record, operation, modifiedFieldNames, details, eOpts) {
    		// this could be optimized but I it's unlikely the user will notice we recalculate the entire store, since this is likely happening when the user modify a different
    		// store/grid
    		var me = this;
    		me.removeAll();
    		me.translateAll();
    	},
    	translateAll : function() {
    		var me = this;
    		var model = me.getModel();
    		var fields = model.getFields();
    		var fieldMap = model.getFieldsMap();
    		var dependentStore = me.getStore();
    		var recordsToBeAdded = [];
    		dependentStore.getGroups().each(function(group) {
    			var aggregations = {};
    			Ext.each(fields, function(field) {
    				Ext.each(group.items, function(record) {
    					var fieldValue = record.get(field.getMapping() || field.getName());
    					var fieldKey = field.getName();
    					var values = aggregations[fieldKey];
    					if (values == undefined) {
    						values = [];
    						aggregations[fieldKey] = values;
    					}
    					values.push(fieldValue);
    				});
    			});
    			var recordData = {};
    			Ext.Object.each(aggregations, function(key, values, myself) {
    				var summaryFn = fieldMap[key].summaryFn;
    				var aggregatedValue;
    				if (!summaryFn) {
    					// take the first value
    					aggregatedValue = values[0];
    				} else {
    					aggregatedValue = summaryFn(values);
    				}
    
    
    				recordData[key] = aggregatedValue;
    			});
    			recordsToBeAdded.push(recordData);
    		});
    		me.add(recordsToBeAdded);
    	}
    });
    
    Ext.define('Nextt.Promise', {
    	extend : 'Ext.data.Model',
    	statics : {
    		storeLoaded : function(storeParam) {
    			return function(){
    				var store = Ext.data.StoreManager.lookup(storeParam);
    				return Nextt.Promise.getDeferredLoaded(store);
    			}
    		},
    		getPromiseStoreLoaded : function(store) {
    			var deferred = new Ext.Deferred();
    	
    			if (store.isLoaded() && !store.isLoading() && !store.hasPendingLoad() ) {
    				deferred.resolve(store.getCount());
    			} else {
    				store.on("load", function(store, records, successful, operation, eOpts) {
    					if (successful) {
    						deferred.resolve(store.getCount());
    					} else {
    						deferred.resolve('failed ' + operation);
    					}
    				}, this, {
    					single: true
    				});
    			}
    			return deferred.promise;
    		}
    	}
    }, function(){
    	var deferred = new Ext.Deferred();
    	deferred.resolve(true);
    	Nextt.Promise.done = deferred.promise;
    });

  2. #2
    Sencha User
    Join Date
    Feb 2013
    Location
    California
    Posts
    11,985
    Answers
    506

    Default

    Thanks for sharing your work with the community!

Similar Threads

  1. [FIXED] Bug in the 2.1 list implementation
    By troels in forum Sencha Touch 2.x: Bugs
    Replies: 4
    Last Post: 6 Dec 2012, 1:12 AM
  2. Security implementation
    By arshad236 in forum Community Discussion
    Replies: 1
    Last Post: 17 Jun 2012, 1:48 AM
  3. EXT CRM implementation
    By lokshu in forum Community Discussion
    Replies: 6
    Last Post: 27 Oct 2008, 8:46 PM
  4. widget implementation
    By wanggwt in forum Community Discussion
    Replies: 3
    Last Post: 11 Jun 2008, 10:20 PM
  5. [2.1] Possible Bug in TriggerField implementation
    By Howard in forum Ext 2.x: Bugs
    Replies: 7
    Last Post: 2 Jun 2008, 9:35 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •