2013-03-02 30 views
11

Tôi có hai mô hình:Xóa mẫu gắn liền với ember dữ liệu

App.User = DS.Model.create({ 
    comments: DS.hasMany('App.Comment') 
}); 

App.Comment = DS.Model.create({ 
    user: DS.belongsTo('App.User') 
}); 

Khi người dùng sẽ bị xóa, nó cũng sẽ xóa tất cả các ý kiến ​​của mình trên backend, vì vậy tôi nên xóa chúng khỏi danh tính client-side bản đồ.

Tôi liệt kê tất cả các nhận xét trên hệ thống từ một nơi khác, vì vậy sau khi xóa người dùng, nó sẽ chỉ gặp sự cố.

Có cách nào để chỉ định loại phụ thuộc này vào liên kết không? Cảm ơn!

Trả lời

9

Tôi sử dụng mixin khi tôi muốn thực hiện hành vi này. Mô hình của tôi được định nghĩa như sau:

App.Post = DS.Model.extend(App.DeletesDependentRelationships, { 
    dependentRelationships: ['comments'], 

    comments: DS.hasMany('App.Comment'), 
    author: DS.belongsTo('App.User') 
}); 

App.User = DS.Model.extend(); 

App.Comment = DS.Model.extend({ 
    post: DS.belongsTo('App.Post') 
}); 

Các mixin bản thân:

App.DeletesDependentRelationships = Ember.Mixin.create({ 

    // an array of relationship names to delete 
    dependentRelationships: null, 

    // set to 'delete' or 'unload' depending on whether or not you want 
    // to actually send the deletions to the server 
    deleteMethod: 'unload', 

    deleteRecord: function() { 
     var transaction = this.get('store').transaction(); 
     transaction.add(this); 
     this.deleteDependentRelationships(transaction); 
     this._super(); 
    }, 

    deleteDependentRelationships: function(transaction) { 
     var self = this; 
     var klass = Ember.get(this.constructor.toString()); 
     var fields = Ember.get(klass, 'fields'); 

     this.get('dependentRelationships').forEach(function(name) { 
      var relationshipType = fields.get(name); 
      switch(relationshipType) { 
       case 'belongsTo': return self.deleteBelongsToRelationship(name, transaction); 
       case 'hasMany': return self.deleteHasManyRelationship(name, transaction); 
      } 
     }); 
    }, 

    deleteBelongsToRelationship: function(name, transaction) { 
     var record = this.get(name); 
     if (record) this.deleteOrUnloadRecord(record, transaction); 
    }, 

    deleteHasManyRelationship: function(key, transaction) { 
     var self = this; 

     // deleting from a RecordArray doesn't play well with forEach, 
     // so convert to a normal array first 
     this.get(key).toArray().forEach(function(record) { 
      self.deleteOrUnloadRecord(record, transaction); 
     }); 
    }, 

    deleteOrUnloadRecord: function(record, transaction) { 
     var deleteMethod = this.get('deleteMethod'); 
     if (deleteMethod === 'delete') { 
      transaction.add(record); 
      record.deleteRecord(); 
     } 
     else if (deleteMethod === 'unload') { 
      var store = this.get('store'); 
      store.unloadRecord(record); 
     } 
    } 
}); 

Lưu ý rằng bạn có thể xác định qua deleteMethod hay không, bạn muốn gửi DELETE yêu cầu API của bạn. Nếu back-end của bạn được cấu hình để xóa các bản ghi phụ thuộc tự động, thì bạn sẽ muốn sử dụng mặc định.

Đây là một số jsfiddle cho biết nó đang hoạt động.

+0

Hey, điều này có vẻ cực kỳ OK! Mặc dù tôi nghĩ rằng 'dữ liệu ember 'sẽ hỗ trợ một cái gì đó như thế trong lõi. Cảm ơn lời giải thích chi tiết như vậy, anh bạn! – josepjaume

+0

Tôi đồng ý. Dữ liệu Ember thiếu một số tính năng chính nhưng nó vẫn còn rất trẻ và cải thiện rất nhanh chóng. – ahmacleod

+1

Dữ liệu Ember không còn hỗ trợ giao dịch, do đó, mã ở trên sẽ cần được sửa đổi để làm việc với các bản dựng gần đây. – ahmacleod

3

Một cách nhanh chóng-và-bẩn sẽ được thêm dòng sau vào mô hình người dùng của bạn

destroyRecord: -> 
    @get('comments').invoke('unloadRecord') 
    @_super() 
0

Tôi thích câu trả lời của @ahmacleod để làm việc với ember-cli 2.13.1ember-data 2.13.0. Tôi đã có một vấn đề với các mối quan hệ lồng nhau và thực tế là sau khi xóa một thực thể từ cơ sở dữ liệu id của nó đã được tái sử dụng. Điều này dẫn đến mâu thuẫn với tàn dư trong mô hình dữ liệu ember.

import Ember from 'ember'; 

export default Ember.Mixin.create({ 
    dependentRelationships: null, 

    destroyRecord: function() { 
     this.deleteDependentRelationships(); 

     return this._super() 
     .then(function (model) { 
      model.unloadRecord(); 

      return model; 
     }); 
    }, 

    unloadRecord: function() { 
     this.deleteDependentRelationships(); 

     this._super(); 
    }, 

    deleteDependentRelationships: function() { 
     var self = this; 
     var fields = Ember.get(this.constructor, 'fields'); 

     this.get('dependentRelationships').forEach(function(name) { 
      self.deleteRelationship(name); 
     }); 
    }, 

    deleteRelationship (name) { 
     var self = this; 
     self.get(name).then(function (records) { 
      if (!records) { 
       return; 
      } 

      var reset = []; 
      if (!Ember.isArray(records)) { 
       records = [records]; 
       reset = null; 
      } 

      records.forEach(function(record) { 
       if (record) { 
        record.unloadRecord(); 
       } 
      }); 

      self.set(name, reset); 
     }); 
    }, 
}); 

Cuối cùng, tôi đã phải thiết lập các mối quan hệ để [] (hasMany) hoặc null (belongsTo). Khác tôi sẽ chạy vào thông báo lỗi sau đây:

Assertion Failed: You cannot update the id index of an InternalModel once set. Attempted to update <id>.

Có lẽ đây là hữu ích cho người khác.

Các vấn đề liên quan