2012-04-16 43 views
5

Tôi đang sử dụng backbone.js để triển khai danh sách bạn bè tên là Roster. xem xương sống của tôi cho bộ sưu tập Roster và cá nhân rosterEntry như sau:Backbone.js: Xóa một mục khỏi bộ sưu tập

Slx.Roster.Views.RosterEntry = Backbone.View.extend({ 
    tagName: "li", 
    className : "rosterEntry clearfix", 
    templateSelector: '#rosterEntryTemplate', 

    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.model.bind('change', this.render); 
     this.model.bind('remove', this.remove); 
     this.template = _.template($("#rosterEntryTemplate").html()); 
    }, 

    remove: function() { 
     debug.log("Called remove event on model"); 
     $(this.el).remove(); 
    }, 
    render: function() { 
     var renderedContent = this.template(this.model.toJSON()); 
     this.id = this.model.Id; 
     $(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent); 
     return this; 
    } 
}); 

    Slx.Roster.Views.Roster = Backbone.View.extend({ 
     el: "div#roster-container", 
     initialize: function() { 
      _.bindAll(this, 'render', 'add', 'remove'); 
      this.template = _.template($("#rosterTemplate").html()); 
      this.collection.bind('reset', this.render); 
      this.collection.bind('add', this.add); 
      this.collection.bind('remove', this.remove); 
     }, 
     add: function (rosterEntry) { 
      var view = new Slx.Roster.Views.RosterEntry(
       { 
        model: rosterEntry 
       }); 
      $(this.el).append(view.render().el); 
     }, 
     remove: function (model) { // if I ommit this then the whole collection is removed!! 
      debug.log("called remomve on collection"); 
     }, 
     render: function() { 
      var $rosterEntries, collection = this.collection; 

      $(this.el).html(this.template({})); 
      $rosterEntries = this.$('#friend-list'); 

      _.each(collection.models, function (model) { 
       var rosterEntryView = new Slx.Roster.Views.RosterEntry({ 
        model: model, 
        collection: collection 
       }); 

       $(this.el).find("ul#friend-list").append(rosterEntryView.render().el); 
      }, this); 

      return this; 
     } 
    }) 

Tôi đang thử nghiệm cho bây giờ bằng cách sử dụng Firebug console và có thể cư trú trong danh sách tốt bằng cách thực hiện như sau:

collection = new Slx.Roster.Collection 
view = new Slx.Roster.Views.Roster({collection:collection}) 
collection.fetch() 

thêm một bộ sưu tập cũng hoạt động tốt, bằng cách thực hiện sau trong Firebug console:

collection.add(new Slx.Roster.Model({username:"mickeymouse"})

rosterEntry mới được thêm vào Roster.

Vấn đề của tôi là collection.remove(5) xóa khỏi bộ sưu tập trong bộ nhớ, nhưng không có gì để cập nhật DOM.

Thật kỳ lạ, nếu tôi sử dụng chức năng remove() từ Chế độ xem Roster, tất cả các mục nhập trong danh sách sẽ bị xóa. Nếu tôi thêm phương thức này mà không có gì trong đó nhưng một nhật ký console, thì phương thức remove trên cả hai khung nhìn Roster và RosterEntry được gọi là - mặc dù tôi không chắc chắn tại sao nhưng chúng không đúng thứ tự!

["Called remove event on model"] 
["called remomve on collection"] 

nếu tôi xóa hàm remove từ mô hình RosterEntry tôi nhận được lỗi này:

TypeError: this.$el is undefined 
this.$el.remove(); 

Tôi đang làm gì sai? Làm cách nào để xóa phần tử khỏi DOM khi nó bị xóa khỏi bộ sưu tập?

Trả lời

2

Tôi nghĩ rằng bạn có một vấn đề với context trong mỗi định nghĩa sự kiện ràng buộc.

Cố gắng thay đổi điều này:

this.model.bind('remove', this.remove); 

Đối với điều này:

this.model.bind('remove', this.remove, this); 

Tôi biết bạn đã cố gắng để giải quyết việc này với bindAll, nhưng bindAll được gói mỗi cuộc gọi đến các phương pháp liệt kê với bối cảnh của đối tượng thực tế, nhưng điều này không thể làm bất cứ điều gì nếu bạn đang gọi phương thức tương tự trên đối tượng khác :).

Cập nhật

Tôi đã đọc nhiều .. trông giống như bindAll và paramater thứ ba của lệnh bind làm giống hệt nhau. Vì vậy, có thể bạn có thể sử dụng cái này hay cái kia.

Các là không hoạt động đúng bindAll trong model.remove là bởi vì bạn quên để thêm nó vào dòng _.bindAll(this, 'render'), hãy tìm trong mã của bạn. Và đề xuất của tôi đã sửa nó vì tôi nói cả hai cách tiếp cận đều giống nhau.

gì tất cả điều này đang làm là đảm bảo rằng các cuộc gọi đến các phương pháp liệt kê (render, remove, ... trong một trường hợp hoặc this.remove trong khác) đang gonna interpretate this như một tham chiếu đến đối tượng thực tế. Điều này có thể trông ngu ngốc nhưng this là rất dễ bay hơi trong JS.

Đừng lo lắng nếu bạn vẫn còn bối rối với điều this, tôi đã xử lý nó lâu và vẫn là not completely cofindent.

Có thể essais like this có thể giúp chúng tôi.

+1

Điều gì làm bạn có nghĩa là tôi có một vấn đề với mọi định nghĩa ràng buộc evenet? Không chắc tôi thực sự hiểu những gì bindall là trung thực với bạn. Tôi chỉ nghĩ rằng tất cả các sự kiện đã được thêm vào bindall. – reach4thelasers

+0

Tham số thứ ba trên hàm kết nối là gì? – reach4thelasers

+0

hoạt động này! Cảm ơn! Hãy suy nghĩ tôi đã sussed ra những gì bindall là cho bằng cách đọc một bài stackoverflow, nhưng tại sao không bindall làm việc? nó dường như làm điều tương tự .... cũng tại sao tôi không cần thêm một 'điều này' trên tuyên bố ràng buộc thu? – reach4thelasers

-1

Phương pháp xóa trên cả hai chế độ xem có thể đang được gọi vì bạn đã bị ràng buộc xóa trên cả mô hình và bộ sưu tập.

Trong RosterEntry:

this.model.bind('remove', this.remove); 

Trong Roster:

this.collection.bind('remove', this.remove); 
+0

Đây không phải là những gì tôi đã có? – reach4thelasers

0

Bạn đã thử những điều sau đây chưa?

this.listenTo(this.model, "remove", this.remove); 

Điều đó có vẻ phù hợp với tôi và tôi thích cách đọc tốt hơn một chút.

Link to Backbone doc

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