2012-10-02 37 views
5

Tôi đã cố gắng tự động thay đổi url bên trong bộ định tuyến nhưng không thể quản lý nó, nó tiếp tục trở lại URL Bộ sưu tập cơ bản. Ở đây tôi đăng mã với 3 bộ sưu tập khác nhau mà ngoài việc trỏ đến ba url khác nhau mà họ làm chính xác như nhau. Tôi chỉ có một model và ba collections phụ thuộc vào mô hình đó và thậm chí là hiển thị cùng một chế độ xem. Làm cách nào tôi có thể thay đổi động url để tôi chỉ có thể tạo một Collection và một Model? Nó là pracitce tốt nhất cho một trường hợp như thế này?Tự động thay đổi url trong Backbone

// MODELS & COLLECTIONS 
    window.Post = Backbone.Model.extend({ 
      urlRoot: function() { 
        return 'http://localhost:5000/json/guides/:id' 
      } 
    }) 

    App.Collections.RecentPosts = Backbone.Collection.extend({ 
      model: Post, 
      url:'http://localhost:5000/json/posts/recent', 
    }) 
    App.Collections.PopularPosts = Backbone.Collection.extend({ 
      model: Post, 
      url:'http://localhost:5000/json/posts/popular', 
    }) 
    App.Collections.FeaturedPosts = Backbone.Collection.extend({ 
      model: Post, 
      url:'http://localhost:5000/json/posts/featured', 
    }) 

    // CONTROLLER 
    App.Controllers.Documents = Backbone.Router.extend({ 
      routes:{ 
      "recent"    : "recent", 
      "popular"   : "popular", 
      "featured"   : "featured", 
      }, 

      recent: function(){ 
       //.... same as featured ? 
      }, 
      popular: function(){ 
       //.... same as featured ? 
      }, 
      featured: function(){ 
        $("#browser").empty(); 
        var collection = new App.Collections.Posts(); 
        collection.fetch({ 
           success: function(col,posts){ 
            new App.Views.GuideView({collection: posts}); 
           }, 
           error: function(error){ 
            console.log(error) 
           } 
         }) 
      } 
    }); 

Trả lời

6

Có nhiều cách khác nhau để thực hiện việc này. Đây là những gì có thể sẽ là 'thực hành tốt nhất'.

App.Controllers.Documents = Backbone.Router.extend({ 
     routes:{ 
     "recent"    : "recent", 
     "popular"   : "popular", 
     "featured"   : "featured", 
     }, 

     initialize: function() { 
      this.collection = new App.Collections.Posts(); 
     }, 

     _showPage: function (config) { 
      $("#browser").empty(); 

      this.collection.fetch({ 
       url: config.url, 
       success: function(col,posts){ 
        new App.Views.GuideView({collection: posts}); 
       }, 
       error: function(error){ 
        console.log(error) 
       } 
      }); 
     }, 

     recent: function(){ 
      this._showPage({url:'http://localhost:5000/json/posts/recent'}); 
     }, 
     popular: function(){ 
      this._showPage({url:'http://localhost:5000/json/posts/popular'}); 
     }, 
     featured: function(){ 
      this._showPage({url:'http://localhost:5000/json/posts/featured'}); 
     } 
}); 

Vì tôi thực sự không biết trang của bạn phức tạp như thế nào, đây có lẽ là điều tốt nhất tôi có thể làm mà không cần thêm thông tin. Tuy nhiên, ý tưởng là "this.collection" được đặt trên khởi tạo bộ định tuyến .. để bạn có thể tiếp tục sử dụng lại nó. Phương thức _showPage thực hiện bất kỳ tác vụ cơ bản nào bạn cần thực hiện để hiển thị trang và các phương thức được gọi bởi các tuyến sử dụng nó để làm bất cứ điều gì cần thực hiện trước khi đi vào chi tiết. Url được chuyển vào cấu hình sẽ chỉ cho bộ sưu tập biết nơi lấy thông tin từ đó - Tôi giả định rằng tất cả dữ liệu của bạn có cùng định dạng và 'cùng một thứ' .. chỉ là các bộ lọc khác nhau.

Bạn có lẽ có thể làm một điều tương tự với App.Views.GuideView:

App.Controllers.Documents = Backbone.Router.extend({ 
     routes:{ 
     "recent"    : "recent", 
     "popular"   : "popular", 
     "featured"   : "featured", 
     }, 

     initialize: function() { 
      this.collection = new App.Collections.Posts(); 
      this.view = new App.Views.GuideView({collection: this.collection}); 
     }, 

     _showPage: function (config) { 
      $("#browser").empty(); 

      this.collection.fetch({ 
       url: config.url, 
       success: _.bind(function(col,posts){ 
        this.view.render(); 
       }, this), 
       error: function(error){ 
        console.log(error) 
       } 
      }); 
     }, 

     recent: function(){ 
      this._showPage({url:'http://localhost:5000/json/posts/recent'}); 
     }, 
     popular: function(){ 
      this._showPage({url:'http://localhost:5000/json/posts/popular'}); 
     }, 
     featured: function(){ 
      this._showPage({url:'http://localhost:5000/json/posts/featured'}); 
     } 
}); 

Các 'làm' chỉ sẽ xây dựng lại quan điểm, và vì bạn đã có bộ sưu tập tham chiếu trong xem như "this.options. bộ sưu tập "(hoặc bạn có thể thêm một 'khởi tạo' để xem và thiết lập this.collection được this.options.collection). Khi bộ sưu tập được cập nhật, tất cả thông tin đó là tham chiếu trong chế độ xem .. do đó không cần phải đặt lại.

+0

Cảm ơn! Nó hoạt động tuyệt vời. Đây là cách tiếp cận ban đầu của tôi nhưng tôi đã không khởi tạo 'Router' và cũng đã làm sai:' fetch ({url: config.url}, success: .... '. Tôi cũng có trong' Router' a 'Home' * chức năng * mà' this.navigate ("phổ biến") 's. Điều đó không hoạt động ... tại sao là? – Maroshii

+0

Tôi nghĩ rằng vì 'điều hướng' được gọi là âm thầm theo mặc định. Hãy thử làm' this.navigate ("phổ biến", {trigger: true}); ' – Stephen

+0

Cảm ơn một lần nữa .... Anh hùng trong ngày! – Maroshii

1

Tôi nghĩ rằng khả năng tốt nhất sẽ là có 3 bộ sưu tập, mỗi bộ sưu tập đều có trên URL và thuộc tính.

Điều này làm cho mã dễ bảo trì hơn khi bạn có thể gán các sự kiện và người nghe khác nhau cho chúng trong một tệp riêng biệt thay vì có "Bộ sưu tập Thiên Chúa" có tất cả logic bên trong.

Tất nhiên bạn vẫn có thể DRY và giữ một đối tượng trợ giúp hoặc bộ sưu tập phụ huynh có mã là bắt buộc tất cả các bộ sưu tập đó.

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