我应该如何处理BackboneJS中的路由?路由时,在新视图之后,我应该触发事件还是直接渲染视图?
以下是两种情况:
触发事件:
routes: {
'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
var viewOrderView = new ViewOrderView();
vent.trigger('order:show', orderId);
}
在我看来,我有:
var ViewOrderView = Backbone.View.extend({
el: "#page",
initialize: function () {
vent.on('order:show', this.show, this);
},
show: function (id) {
this.id = id;
this.render();
},
render: function () {
var template = viewOrderTemplate({ id: this.id });
this.$el.html(template);
return this;
}
});
或者,我应该走这条路吗?
routes: {
'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
var viewOrderView = new ViewOrderView({id : orderId });
viewOrderView.render();
}
在我看来,我有:
var ViewOrderView = Backbone.View.extend({
el: "#page",
initialize: function () {
//init code here
},
render: function () {
var template = viewOrderTemplate({ id : this.id});
this.$el.html(template);
return this;
}
});
我认为这是第一个场景 - 鉴于骨干是事件驱动的,但第二个显然拥有更少的代码。
另外,我认为第三种情况是将视图代码保留在第一种情况中,但是抓住第二种情况的路由器情景......在导航上呈现视图,但是如果我想触发该事件则暴露事件别处。
思想?
答案 0 :(得分:5)
因此,所有骨干问题通常都会得到许多合理的答案。在这种情况下,我相信你的第二个例子是一个更规范/典型的主干模式。抛开处理加载微调器和在数据加载后更新的棘手问题,路由器中的简化基本模式将是:
routes: {
'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
//Use models to represent your data
var orderModel = new Order({id: orderId});
//models know how to fetch data for themselves given an ID
orderModel.fetch();
//Views should take model instances, not scalar model IDs
var orderView = new OrderView({model: orderModel});
orderView.render();
//Exactly how you display the view in the DOM is up to you
//document.body might be $('#main-container') or whatever
$(document.body).html(orderView.el);
}
我认为这是教科书模式。同样,谁触发获取数据并在数据到达后重新渲染的问题是棘手的。我认为最好是视图知道如何在模型获取数据之前呈现自身的“加载”版本,然后当模型在获取完成后触发更改事件时,视图会使用加载的模型数据重新呈现自身。但是,有些人可能会将这种逻辑放在别处。 This article on building the next soundcloud我认为代表了许多非常好的“最先进”的主干模式,包括他们如何处理未获得成功的模型。
通常,您可以根据需要使用回调或事件对事物进行编码。但是,一个好的经验法则是问自己一些问题:
如果两者都是“是”,那么事件应该是合适的。如果两者都是“否”,那么直接的函数逻辑就更合适了。在“导航到此URL触发此视图”的情况下,通常两个问题的答案都是“否”,因此您可以将该逻辑编码到路由器的路由处理程序方法中并使用它完成。
答案 1 :(得分:3)
我会使用第二种情况。看不到使用第一种方法的任何好处。它会以这种方式产生更多的意义(但仍有争议):
/* ... */
routes: {
'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
vent.trigger('order:show', orderId);
}
/* ... */
vent.on('order:show', function(orderId) {
var viewOrderView = new ViewOrderView();
viewOrderView.render();
});
var ViewOrderView = Backbone.View.extend({
el: "#page",
initialize: function (options) {
this.orderId = options.orderId;
},
render: function () {
var template = viewOrderTemplate({
id: this.orderId
});
this.$el.html(template);
return this;
}
});
这样至少你可以在不更新网址的情况下触发路由操作。但可能使用Backbone.router.viewOrder(1)
可能会达到同样的效果。事件非常强大,但如果我真的不需要,我就不会使用它们。