我正在开发一个使用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 :(得分:2)
你可以这样做。您可以使用集合而不是模型执行类似的操作,但似乎您不想获取/显示整个集合?
使用这种类型的解决方案(我认为类似于@mpm的建议),您的应用将正确处理浏览器刷新,后退/前进导航。你基本上有一个MainView,它真的更像是一个app控制器。它处理由路由器或用户交互(单击项目视图上的查找或返回索引按钮)触发的事件。
很多这些想法都归功于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中,您将在应用启动时创建,而不是在路由器中创建:
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);
}
然后在IndexView中,使用已获取的模型触发“show-item-view”事件。
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();
}
});
},
我不认为这完全是完美的,但我希望它可以指出你的方向。