我正在构建一个带有搜索表单和一些结果的简单 Backbone 应用程序。我想:
- 允许用户更改“order by”选择字段的值,并适当地更新 URL 和结果
- 确保当用户通过预设 URL 到达时,显示正确的结果,并且所选表单元素与 URL 和结果匹配。
我想我已经找到了正确的控制流程来使用,但我真的很想找人检查一下。基本上,我让我的视图直接更新 URL,然后路由器完成更新模型的工作。然后其他视图听模型。
好像还可以,但是我得在View中手动构造URL,在Router中再解析一遍,感觉是重复的。所以很高兴知道这是否是在 Backbone 中做事的正确方法,或者我是否可以做得更好。
这是伪代码:
User changes value of select to "price-asc"
|
|
v
Form view hears change event, and
updates the URL to #order-by-price-asc
|
|
v
Router looks at new route, <----- User loads page, with
sets model value #order-by-price-asc route
|
|
v
Results view hears change
to model value, loads in
new results via Ajax
这是代码:
HTML:
<select id="order">
<option value=''></option>
<option value='price-asc'>price (low to high)</option>
<option value='price-desc'>price (high to low)</option>
</select>
<div id="results"></div>
JS:
var SearchModel = Backbone.Model.extend({
initialize: function() {
this.bind("change:query", function() {
this.performSearch();
});
},
performSearch: function() {
// Will eventually do Ajax search here,
// but for the moment, just bind to query.
this.set("results", this.get("query"));
},
});
var SearchFormView = Backbone.View.extend({
el: $('#order'),
events: {
"change": "updateURL"
},
initialize: function() {
this.model.on("change:results", this.updateFormClasses, this);
},
updateFormClasses: function(model, query) {
this.$el.val(query);
},
updateURL: function(e) {
var url = '';
($('#order').val() !== '') ? url += "/by-" + $('#order').val() : null;
SearchApp.navigate(url, {trigger: true});
}
});
var SearchResultsView = Backbone.View.extend({
el: "#results",
initialize: function() {
this.model.on("change:results", this.displayResults, this);
},
displayResults: function(model, query) {
this.$el.text(query)
}
});
var AppRouter = Backbone.Router.extend({
routes: {
"*str": "index",
},
initialize: function() {
this.searchModel = new SearchModel();
this.searchFormView = new SearchFormView({
model: this.searchModel
});
this.searchResultsView = new SearchResultsView({
model: this.searchModel
});
},
index: function(str) {
var ordering = str.match(/by-.*/gi);
if (ordering !== null) {
this.searchModel.set({"query": ordering[0].replace('by-','')});
}
}
});
var SearchApp = new AppRouter();
Backbone.history.start({});