2013-02-16 83 views
1

我正在開發一個使用require.js的骨幹應用程序。骨幹視圖,模型和路由器的角色

我希望用戶輸入模型的'id',然後將其重定向到該模型的視圖(如果存在),或者如果不存在則顯示錯誤消息。這聽起來非常簡單,但我很難弄清楚每個組件的角色。

在下面的應用程序中,用戶將通過輸入(帶有id'modelId')和按鈕(帶有類屬性'lookup')來到索引頁面。

以下一段代碼是路由器。

define(['views/index', 'views/myModelView', 'models/myModel'], 
    function(IndexView, MyModelView, myModel) { 
    var MyRouter = Backbone.Router.extend({ 
     currentView: null, 

     routes: { 
      "index": "index", 
      "view/:id": "view" 
     }, 

     changeView: function(view) { 
      if(null != this.currentView) { 
       this.currentView.undelegateEvents(); 
      } 
      this.currentView = view; 
      this.currentView.render(); 
     }, 

     index: function() { 
      this.changeView(new IndexView()); 
     }, 

     view: function(id) { 
      //OBTAIN MODEL HERE? 
      //var model 
      roter.changeView(new MyModelView(model)) 
     } 

    }); 

    return new MyRouter(); 
}); 

下面這段代碼是索引視圖

define(['text!templates/index.html', 'models/myModel'], 
    function(indexTemplate, MyModel) { 
    var indexView = Backbone.View.extend({ 
     el: $('#content'), 

     events: { 
      "click .lookup": "lookup" 
     }, 

     render: function() { 
      this.$el.html(indexTemplate); 
      $("#error").hide(); 
     }, 

     lookup: function(){ 
      var modelId = $("#modelId").val() 
      var model = new MyModel({id:modelId}); 
      model.fetch({ 
       success: function(){ 
        window.location.hash = 'view/'+model.id; 
       }, 
       error: function(){ 
        $("#error").text('Cannot view model'); 
        $("#error").slideDown(); 
       } 
      }); 
     }, 
    }); 
    return indexView 
}); 

我無法弄清楚什麼是它似乎是更好的選擇是在索引視圖來查找模型(所以如果用戶要求一個不存在的模型,並且還要保持路由器清潔,它可以顯示一條錯誤消息。但問題是,當view /:id路由器被觸發時,路由器現在沒有引用該模型。它應該如何在view()函數中保留模型?

我想它可以做另一個獲取,但這似乎是多餘的和錯誤的。或者也許應該是路由器和視圖共享的一些全局對象(即索引視圖可以放入模型),但這似乎是緊密耦合。

+0

路由器可以擁有一個模型集合,只需查詢正確模型的集合即可。這是收藏的目的。 – mpm 2013-02-16 02:15:34

+0

但是,「索引視圖」(獲取模型的工作)和路由器(將模型賦予應該顯示它的視圖)之間的集合是如何共享的? – Kyle 2013-02-16 02:20:09

+0

集合可以是路由器的一個屬性,你可以在初始化函數中傳遞它,然後使用this.collection或其他什麼,你明白嗎?你正在談論緊耦合,但是如果你進行依賴注入,那麼耦合並不緊密。 – mpm 2013-02-16 02:22:16

回答

2

你可以做這樣的事情。你可以用一個集合而不是一個模型做類似的事情,但是你似乎不想獲取/顯示整個集合?

有了這種類型的解決方案(我認爲類似於@mpm的建議),您的應用程序將處理瀏覽器刷新,正確地返回/轉發導航。你基本上有一個MainView,它更像一個應用程序控制器。它處理由路由器或用戶交互觸發的事件(單擊查看或項目視圖上的返回索引按鈕)。

對於很多這些想法,請登錄Derick Bailey

在路由器中。這些現在只在用戶通過更改URL或後退/前進進行導航時觸發。

index: function() { 
     Backbone.trigger('show-lookup-view'); 
    }, 

    view: function(id) { 
     var model = new MyModel({id: id}); 
     model.fetch({ 
      success: function(){ 
       Backbone.trigger('show-item-view', model); 
      }, 
      error: function(){ 
       // user could have typed in an invalid URL, do something here, 
       // or just make the ItemView handle an invalid model and show that view... 
      } 
     }); 
    } 

在新的MainView,您將創建應用程序啓動時,而不是在路由器:在IndexView

el: 'body', 

initialize: function (options) { 
    this.router = options.router; 

    // listen for events, either from the router or some view. 
    this.listenTo(Backbone, 'show-lookup-view', this.showLookup); 
    this.listenTo(Backbone, 'show-item-view', this.showItem); 
}, 

changeView: function(view) { 
    if(null != this.currentView) { 
     // remove() instead of undelegateEvents() here 
     this.currentView.remove(); 
    } 
    this.currentView = view; 
    this.$el.html(view.render().el); 
}, 

showLookup: function(){ 
    var view = new IndexView(); 
    this.changeView(view); 
    // note this does not trigger the route, only changes hash. 
    // this ensures your URL is right, and if it was already #index because 
    // this was triggered by the router, it has no effect. 
    this.router.navigate('index'); 
}, 

showItem: function(model){ 
    var view = new ItemView({model: model}); 
    this.changeView(view); 
    this.router.navigate('items/' + model.id); 
} 

然後,觸發與已獲取模型「顯示項目視圖」事件。

lookup: function(){ 
     var modelId = $("#modelId").val() 
     var model = new MyModel({id:modelId}); 
     model.fetch({ 
      success: function(){ 
       Backbone.trigger('show-item-view', model); 
      }, 
      error: function(){ 
       $("#error").text('Cannot view model'); 
       $("#error").slideDown(); 
      } 
     }); 
    }, 

我不認爲這完全是完美的,但我希望它可以指向一個很好的方向。