【问题标题】:ExtJS waiting for multiple stores to loadExtJS 等待多个商店加载
【发布时间】:2012-03-11 21:02:56
【问题描述】:

我将如何等待多个商店加载?我有一个案例,只有在加载两个不同的商店时才需要做一些工作,所以使用一个商店的store.on("load", fn) 是不够的。

【问题讨论】:

标签: javascript extjs extjs4 store


【解决方案1】:

我使用连锁装载商店来解决这个问题。

缺点:比应有的速度慢。

chainStoreLoad :function (stores, lastCall, idx)
{
    if (idx === stores.length) {
        if ("function" === typeof lastCall) {
            lastCall.call ();
        }
        return;
    }
    stores[idx].load (function (r,o,s) {
        Jx.chainStoreLoad (stores, lastCall, idx + 1);
    });
}

例子:

Jx.chainStoreLoad (
    [
        this.storeAssetType
    ,   this.storeAssetProcurement
    ,   this.storeAssetStatus
    ,   this.storeAssetLocation
    ,   this.storeSystemUser
    ]
,   function ()
    {
        self.panel.doRefresh (perm);
    }
,   0);

【讨论】:

    【解决方案2】:

    当有几家商店需要等待时,我们会使用它:

    Ext.define('Ext.ux.StoreLoadCoordinator', {
    mixins: {
        observable: 'Ext.util.Observable'
    },
    resetStoreLoadStates: function() {
        this.storeLoadStates = {};              
    
        Ext.each(this.stores, function(storeId) {
            this.storeLoadStates[storeId] = false;
        }, this);       
    },    
    isLoadingComplete: function() {
        for (var i=0; i<this.stores.length; i++) {
            var key = this.stores[i];
    
            if (this.storeLoadStates[key]==false) {
                return false;
            }
        }
    
        return true;        
    },    
    onStoreLoad: function(store, records, successful, eOpts, storeName) {
        this.storeLoadStates[store.storeId] = true;
    
        if (this.isLoadingComplete()==true) {
            this.fireEvent('load');
            this.resetStoreLoadStates();
        }
    },    
    constructor: function (config) {
        this.mixins.observable.constructor.call(this, config);
    
        this.resetStoreLoadStates();
    
        Ext.each(this.stores, function(storeId) {
            var store = Ext.StoreManager.lookup(storeId);
    
            store.on('load', Ext.bind(this.onStoreLoad, this, [storeId], true));
        }, this);
    
        this.addEvents(
            'load'            
        );
    }});
    

    要使用它,请传入相关 storeIds 的数组:

    var store1 =  Ext.create('Ext.data.Store', {
        storeId: 'Store1',
        .... (rest of store config)
    }});        
    
    var store2 =  Ext.create('Ext.data.Store', {
        storeId: 'Store2',
        .... (rest of store config)
    }});        
    
    
    var coordinatior = Ext.create('Ext.ux.StoreLoadCoordinator', {
        stores: ['Store1', 'Store2'],
        listeners: {
            load: function() {
               // Do post-load work
            }
        }
    });         
    

    这将为您提供单个加载事件来处理多个商店。请注意,这需要 Ext 4.x 或更高版本。

    【讨论】:

    • 太棒了!谢谢
    【解决方案3】:

    通常我会避免这个问题,因为我努力尽量减少客户端/服务器往返并提高性能: 我在商店中将 autoLoad 设置为 false,然后执行显式 ajax 请求,一次获取所有商店的数据,然后使用 store.loadData() 直接将其设置到每个商店。 缺点当然是它需要更多的代码并导致更紧密的耦合。

    【讨论】:

      【解决方案4】:

      我有一些项目需要在处理数据之前加载多个商店。我在它们上添加了一个回调,以检查Ext.data.StoreManager 中的每个项目是否已加载,如果是,它将对数据执行我需要的操作。

      要将商店添加到 StoreManager,您只需在其配置中给它一个 storeId,如下所示:

      var store1 = Ext.create('Ext.data.Store', {
          model: myModel,
          storeId: 'store1', //<-- adds this to Ext.data.StoreManager
          proxy: {
              type: 'ajax', 
              url: 'url...',
              reader: 'json'
          },
          autoLoad: {
              callback: initData
          }
      });
      
      var store2 = Ext.create('Ext.data.Store', {
          model: myModel,
          storeId: 'store2',
          proxy: {
              type: 'ajax', 
              url: 'url...',
              reader: 'json'
          },
          autoLoad: {
              callback: initData
          }
      });
      
      // Initialize store dependencies when all stores are loaded
      function initData() {
          var loaded;
          Ext.data.StoreManager.each( function(store) {
              loaded = !store.isLoading();       
              return loaded;
          });
          if(loaded) {
              // do stuff with the data
          }
      }
      

      【讨论】:

      • 不确定,但我认为否决票是由于loaded = !store.isLoading(); 而应该是loaded &amp;= !store.isLoading();。请参阅此jsfiddle。无论如何都应该有评论,以帮助我们所有人:)
      【解决方案5】:

      我认为您可以为两个商店添加负载侦听器,并检查另一个是否完成...

      this.getStore('store1').on('load',function(store){
         if (this.getStore('store2').isLoading() == false ){
           // callMethod to perform action ....
         }
      },this);
      
      this.getStore('store2').on('load',function(store){
         if (this.getStore('store1').isLoading() == false ){
            // callMethod to perform action....
         }
      },this);
      

      我认为这种方式只有在它们都被加载时才会调用该方法,前提是您知道两者都已发出加载请求。

      【讨论】:

        猜你喜欢
        • 2013-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-18
        • 1970-01-01
        • 2016-04-01
        • 1970-01-01
        • 2013-03-17
        相关资源
        最近更新 更多