2012-10-02 13 views
5

Próbowałem dynamicznie zmieniać adres URL w routerze, ale nie mogłem tego zrobić, a on powraca do podstawowego adresu URL kolekcji. Tutaj napisałem kod z 3 różnymi kolekcjami, które oprócz wskazania trzech różnych adresów URL, robią dokładnie to samo. Mam tylko jeden model i trzy collections, które zależą od tego modelu, a nawet renderowania tego samego widoku. Jak mogę dynamicznie zmieniać url, więc mogę utworzyć tylko jeden Collection i jeden Model? Czy to najlepszy sposób na taki przypadek?Dynamicznie zmieniający się adres URL w sieci szkieletowej

// 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) 
           } 
         }) 
      } 
    }); 

Odpowiedz

6

Istnieje wiele różnych sposobów robienia tego. Oto, co prawdopodobnie będzie "najlepszą praktyką".

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'}); 
     } 
}); 

Ponieważ ja naprawdę nie wiem, jak skomplikowana strona dostanie, to chyba najlepsze, co mogę zrobić bez więcej informacji. Ale pomysł polega na tym, że "this.collection" jest ustawione na inicjalizacji ruterów, aby można było ponownie go używać. Metoda _showPage wykonuje wszelkie podstawowe zadania, które trzeba wykonać, aby wyświetlić stronę, a metody wywoływane przez trasy wykorzystują ją do wykonania podstawowych czynności, zanim przejdą do szczegółów. Adres URL przekazany do konfiguracji po prostu powie zbiorze, skąd pobrać informacje - zakładam, że wszystkie dane mają ten sam format i "to to samo" ... tylko różne filtry.

Prawdopodobnie można zrobić coś podobnego z 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'}); 
     } 
}); 

do „renderowanie” byłoby po prostu odbudować pogląd, a ponieważ masz już kolekcję odwołanie w widoku jako „this.options. kolekcja "(lub możesz dodać" initialize "do widoku i ustawić this.collection to this.options.collection). Gdy kolekcja zostanie zaktualizowana, wszystkie te informacje są przez odniesienie w widoku .. więc nie trzeba go resetować.

+0

Dzięki! Działa świetnie. To było moje początkowe podejście, ale nie zainicjowałem 'Routera 'i również zrobiłem to źle:' fetch ({url: config.url}, success: .... '. Mam również w' Router 'a 'Home' * funkcja * że' this.navigate ("popularna") 's. To nie działa ... dlaczego tak jest? – Maroshii

+0

Myślę, że ponieważ" nawigacja "jest domyślnie wywoływana w trybie cichym. Spróbuj tego' this.navigate ("popularne", {trigger: true}); ' – Stephen

+0

Jeszcze raz dziękuję .... Bohater dnia! – Maroshii

1

Uważam, że najlepszym rozwiązaniem byłoby posiadanie 3 kolekcji, z których każda zawiera adres URL i właściwości.

Ułatwia to obsługę kodu, ponieważ można przypisać różne zdarzenia i słuchaczy w osobnym pliku, zamiast mieć "kolekcję Boga", która zawiera całą logikę.

Oczywiście nadal możesz być SUCHĄ i zachować obiekt pomocniczy lub kolekcję rodziców z kodem, który jest commmon do wszystkich tych kolekcji.

Powiązane problemy