0

目標は、動的データ セットにバッファ ストアを使用することです。ワークフローは次のとおりです。

  1. 一部のデータはサーバーに既に存在します。
  2. クライアントは、バッファリングされたストアと無限グリッドを使用してデータを処理します。
  3. アプリケーションが実行されると、ストアがロードされ、「load」イベントによってグリッドが最後のメッセージまでスクロールされます。
  4. サーバーにいくつかのレコードが追加されます。
  5. クライアントはプッシュ通知を受け取り、ストアのリロードを実行します。topic.store.load({addRecords: true});
  6. load イベントが実行され、最後のメッセージまでスクロールしようとしますが、失敗します。

TypeError: offsetsTo は null e = Ext.fly(offsetsTo.el || offsetsTo, '_internal').getXY();

グリッド ビューが更新されず、追加されたレコードが表示されず、その場所の空白のみが表示されるようです。グリッド ビューを正しく更新するにはどうすればよいですか?

ストアの初期化:

Ext.define('orm.data.Store', {
  extend: 'Ext.data.Store',
  requires: ['orm.data.writer.Writer'],
  constructor: function (config) {
    Ext.apply(this, config);
    this.proxy = Ext.merge(this.proxy, {
      type: 'rest',
      batchActions: true,
      reader: {
        type: 'json',
        root: 'rows'
      },
      writer: {
        type: 'orm'
      }
    });
    this.callParent(arguments);
  }
});

Ext.define('akma.chat.model.ChatMessage', {
  extend:'Ext.data.Model',
  fields:[
    { name:'id', type:'int', defaultValue : undefined },
    { name:'createDate', type:'date', dateFormat:'Y-m-d\\TH:i:s', defaultValue : undefined },
    { name:'creator', type:'User', isManyToOne : true, defaultValue : undefined },
    { name:'message', type:'string', defaultValue : undefined },
    { name:'nameFrom', type:'string', defaultValue : undefined },
    { name:'topic', type:'Topic', isManyToOne : true, defaultValue : undefined }
  ],
  idProperty: 'id'
});



Ext.define('akma.chat.store.ChatMessages', {
   extend: 'orm.data.Store',
   requires: ['orm.data.Store'],
   alias: 'store.akma.chat.store.ChatMessages',
   storeId: 'ChatMessages',
   model: 'akma.chat.model.ChatMessage',
   proxy: {
   url:  'http://localhost:8080/chat/services/entities/chatmessage'
  }
});

var store = Ext.create('akma.chat.store.ChatMessages', {
  buffered: true,
  pageSize: 10,
  trailingBufferZone: 5,
  leadingBufferZone: 5,
  purgePageCount: 0,
  scrollToLoadBuffer: 10,
  autoLoad: false,
  sorters: [
    {
      property: 'id',
      direction: 'ASC'
    }
  ]
});

グリッドの初期化:

Ext.define('akma.chat.view.TopicGrid', {
  alias: 'widget.akma.chat.view.TopicGrid',
  extend: 'akma.chat.view.grid.DefaultChatMessageGrid',
  requires: ['akma.chat.Chat', 'akma.UIUtils', 'Ext.grid.plugin.BufferedRenderer'],
  features: [],
  hasPagingBar: false,
  height: 500,
  loadedMsg: 0,
  currentPage: 0,
  oldId: undefined,
  forceFit: true,
  itemId: 'topicGrid',
  selModel: {
    pruneRemoved: false
  },
  multiSelect: true,
  viewConfig: {
    trackOver: false
  },
  plugins: [{
    ptype: 'bufferedrenderer',
    pluginId: 'bufferedrenderer',
    variableRowHeight: true,
    trailingBufferZone: 5,
    leadingBufferZone: 5,
    scrollToLoadBuffer: 10
  }],
  tbar: [{
    text: 'unmask',
    handler: function(){
      this.up('#topicGrid').getView().loadMask.hide();
    }
  }],

  constructor: function (config) {

    this.topicId = config.topicId;
    this.store = akma.chat.Chat.getMessageStoreInstance(this.topicId);
    this.topic = akma.chat.Chat.getTopic(this.topicId);

    var topicPanel = this;

    this.store.on('load', function (store, records) {
      var loadedMsg = store.getTotalCount();
      var pageSize = store.pageSize;
      store.currentPage = Math.ceil(loadedMsg/pageSize);
        if (records && records.length > 0) {
          var newId = records[0].data.id;
          if (topicPanel.oldId) {
            var element;
            for (var i = topicPanel.oldId; i < newId; i++) {
              element = Ext.get(i + '');
              topicPanel.blinkMessage(element);
            }
          }
          topicPanel.oldId = records[records.length-1].data.id;
          var view = topicPanel.getView();
          view.refresh();
          topicPanel.getPlugin('bufferedrenderer').scrollTo(store.getTotalCount()-1);
        }
    });

    this.callParent(arguments);
    this.on('afterrender', function (grid) {
      grid.getStore().load();
    });
    var me = this;
    akma.UIUtils.onPasteArray.push(function (e, it) {
      if(e.clipboardData){
        var items = e.clipboardData.items;
        for (var i = 0; i < items.length; ++i) {
          if (items[i].kind == 'file' && items[i].type.indexOf('image/') !== -1) {
            var blob = items[i].getAsFile();
            akma.chat.Chat.upload(blob, function (event) {
              var response = Ext.JSON.decode(event.target.responseText);
              var fileId = response.rows[0].id;
              me.sendMessage('<img src="/chat/services/file?id=' + fileId + '" />');
            })
          }
        }
      }
    });
    akma.UIUtils.addOnPasteListener();
  },
  sendMessage: function(message){
    if(message){
      var topicGrid = this;
      Ext.Ajax.request({
        method: 'POST',
        url: topicGrid.store.proxy.url,
        params:{
          rows: Ext.encode([{"message":message,"topic":{"id":topicGrid.topicId}}])
        }
      });
    }
  },
  blinkMessage: function (messageElement) {
    if (messageElement) {
      var blinking = setInterval(function () {
        messageElement.removeCls('red');
        messageElement.addCls('yellow');
        setTimeout(function () {
          messageElement.addCls('red');
          messageElement.removeCls('yellow');
        }, 250)

      }, 500);
      setTimeout(function () {
        clearInterval(blinking);
        messageElement.addCls('red');
        messageElement.removeCls('yellow');
      }, this.showInterval ? this.showInterval : 3000)
    }
  },
  columns: [        {
      dataIndex: 'message',
      text: 'Message',
      renderer: function (value, p, record) {
        var firstSpan = "<span id='" + record.data.id + "'>";
        var creator = record.data.creator;
        return Ext.String.format('<div style="white-space:normal !important;">{3}{1} : {0}{4}</div>',
            value,
            creator ? '<span style="color: #' + creator.chatColor + ';">' +     creator.username + '</span>' : 'N/A',
            record.data.id,
            firstSpan,
            '</span>'
        );
      }
    }
  ]
});

upd : 問題は View にないようです。bufferedrenderer プラグインは、レコードにスクロールするように結び付けます。コールバック関数を実行します:

       callback: function(range, start, end) {

            me.renderRange(start, end, true);

            targetRec = store.data.getRange(recordIdx, recordIdx)[0];

.....

 store.data.getRange(recordIdx, recordIdx)[0] 

ストア内の最後のレコードを取得しようとします。....

 Ext.Array.push(result, Ext.Array.slice(me.getPage(pageNumber), sliceBegin, sliceEnd));

getPage は指定されたページのすべてのレコードを返しますが、最後のレコードが欠落しています。つまり、ストアが完全に更新されていません。

修正方法はありますか?

4

2 に答える 2

4

問題は、store.load() がストア PageMap を新しいデータで埋めないことです。最も簡単な修正方法は、代わりに store.reload() を使用することです。

于 2013-06-13T04:13:33.857 に答える