2013-02-16 52 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(); 
      } 
     }); 
    }, 

我不认为这完全是完美的,但我希望它可以指向一个很好的方向。