2011-10-24 24 views
9

Tôi đang sử dụng ExtJS 4 và có một Ext.data.Store với một proxy ajax và api:Hủy store.remove sau khi cuộc gọi máy chủ trong ExtJS 4

var gridStore = Ext.create('Ext.data.Store', { 
    autoSync: true, 
    proxy: { 
     type: 'ajax', 
     api: { 
      read: 'myurl', 
      create: 'myurl', 
      update: 'myurl', 
      destroy: 'myurl' 
     }, 
     reader: { 
      type: 'json', 
      successProperty: 'success', 
      root: 'data', 
      messageProperty: 'message' 
     }, 
     writer: { 
      type: 'json', 
      writeAllFields: false, 
      root: 'data' 
     }, 
     listeners: { 
      exception: function(proxy, response, operation){ 
       Ext.MessageBox.show({ 
        title: 'Server error', 
        msg: operation.getError(), 
        icon: Ext.MessageBox.ERROR, 
        buttons: Ext.Msg.OK 
       }); 
      } 
     } 
    ... 

Khi tôi sử dụng chức năng cập nhật và máy chủ của tôi trả về một đối tượng json với success:false (vì anh ấy đã nhập sai điều gì đó) trường trong lưới liên kết của tôi vẫn được đánh dấu là đã thay đổi và người dùng có tùy chọn thay đổi giá trị sai của mình.

Điều đó hoạt động tốt.

Nhưng khi tôi loại bỏ một bản ghi từ các cửa hàng ...

var store = Ext.StoreManager.lookup('gridStore'); 
store.remove(store.getById(id)); 

... sau đó ExtJS loại bỏ hồ sơ này từ cửa hàng đầu tiên và gọi api ajax sau đó. Vì vậy, khi tiêu diệt api trả về success:false thông báo được hiển thị là ngoại lệ như trong api cập nhật, điều đó tốt, nhưng hồ sơ của tôi đã bị xóa khỏi cửa hàng! Ví dụ, ngoại lệ từ máy chủ nói rằng bạn không thể xóa bản ghi này vì bất cứ điều gì nhưng nó đã bị xóa trong cửa hàng.

Làm thế nào để hủy bỏ việc loại bỏ cửa hàng sau khi đồng bộ hóa máy chủ? Tôi muốn hồ sơ lưu lại trong cửa hàng nếu máy chủ trả về success:false.

Bất kỳ ý tưởng nào? Có thể là một lỗi?


CẬP NHẬT SOLUTION

Dựa trên anwer Ryan, tôi đổi người nghe ngoại lệ như sau, trong đó hoạt động rất tốt:

listeners: { 
    exception: function(proxy, response, operation){ 
     Ext.MessageBox.show(...); 
     // get the removed records and insert them where they have been 
     var removedRecords = gridStore.getRemovedRecords(); 
     for(var i=0; i<removedRecords.length; i++){ 
      var record = removedRecords[i]; 
      gridStore.insert(record.index, record); 
     } 
    } 
} 
+0

Có thể là lỗi hoặc cần tìm hiểu mã nguồn để xem điều gì xảy ra. Hmm. Câu hỏi thú vị. Thấy điều này trước đây, nhưng tôi đã khắc phục điều này bằng cách tải lại cửa hàng. Không hiệu quả nhưng nó tốt cho dữ liệu nhỏ. –

+3

Đẹp nhất :) Nhưng bạn quên thêm 'gridStore.removed = []' else nếu bạn loại bỏ mục đó một lần nữa bạn sẽ có bản sao (sau đó nó vẫn còn trong mảng bị loại bỏ) – VDP

Trả lời

5

Chỉ cần mở rộng mã bạn đã cho, đặc biệt là listeners diện tích:

listeners: { 
     exception: function(proxy, response, operation){ 
      Ext.MessageBox.show({ 
       title: 'Server error', 
       msg: operation.getError(), 
       icon: Ext.MessageBox.ERROR, 
       buttons: Ext.Msg.OK 
      }); 
      gridStore.add(gridStore.getRemovedRecords()); 
     } 
    } 
+0

Cảm ơn rất nhiều, đó là cách chính xác. Tôi đã thay đổi giải pháp của bạn một chút, hãy xem các câu hỏi đã cập nhật của tôi, bởi vì nếu bạn chỉ thêm các bản ghi, chúng sẽ được thêm vào cuối danh sách nhưng chúng nên ở nơi chúng đã ở trước. – Marc

2

Tôi đang sử dụng model.destroy, đây là những gì tôi sử dụng để xóa các mục đặc biệt từ lưới:

   text : 'Delete', 
       itemId : 'delete', 
       scope : this, 
       handler : function() { 
        var selection = grid.getView().getSelectionModel().getSelection()[0]; 
        if(selection) { 
         selection.destroy({ 
          failure : function() { 
           console.log('Record could not be deleted.'); 
          }, 
          success : function() { 
           store.remove(selection); 
           console.log('Record successfuly removed.'); 
          }, 

         }); 
        } 
       } 
+0

đẹp. chỉ phù hợp với một bản ghi duy nhất. –

6

Kỹ thuật chèn không làm việc cho tôi, hồ sơ lấy ra vẫn được đánh dấu để loại bỏ trên các hoạt động đồng bộ tiếp theo. Tôi đang sử dụng Ext.data.Store.rejectChanges() cho mục đích này.

+0

Đó không phải là phương pháp mặc định? Bạn đã sử dụng [triển khai này] (http://www.sencha.com/forum/showthread.php?141982-commitChanges-and-rejectChanges-for-the-Store-in-ExtJS-4)? – VDP

+0

Phương thức đó tồn tại trong ExtJS 4.1.1a. Không chắc chắn khoảng 4.0 hoặc phiên bản ở giữa.Đây sẽ là câu trả lời đúng. –

2

Tôi đang sử dụng chức năng gọi lại 'thành công', 'lỗi' hoặc 'gọi lại' khi đồng bộ hóa. Tôi hy vọng phương pháp này có thể giúp bạn.

store.remove(records); 
store.sync({ 
    success: function (proxy, operations) { 
     // pop success message 
    }, failure: function (proxy, operations) { 
     // resume records 
     store.rejectChanges(); 
    } 
}); 
Các vấn đề liên quan