Backbone 体系结构和视图管理
Backbone architecture and view management
我正在纠结何时销毁 backbone 视图。我知道我需要在某处破坏视图,但我不确定在哪里。
我在 router.js
中有以下代码
routes: {
"names/search": "nameSearch",
"companies/search": "companySearch"
},
initialize: function(){
Backbone.history.start();
this.navigate("#/", true);
}
nameSearch: function () {
require(["app/views/RecordSearch"], function (RecordSearchView) {
var obj = {};
obj.Status = [utils.xlate("On Assignment"), utils.xlate("Candidate")];
var view = new RecordSearchView({ model: obj, el: $(".content") }, { "modelName": "Candidate" });
view.delegateEvents();
});
},
companySearch: function () {
require(["app/views/RecordSearch"], function (RecordSearchView) {
var view = new RecordSearchView({ model: {}, el: $(".content") }, { "modelName": "Company" });
view.delegateEvents();
});
}
然后在 RecordSearchView.js 中,我有以下函数,当用户单击搜索按钮时调用该函数
doSearch: function () {
require(["app/utils/SearchHelper", "app/models/" + modelName, "app/views/SearchResults"], function (SearchHelper, Model, SearchResultsView) {
var obj = $("#searchForm").serializeArray();
var params = SearchHelper.getQuery(obj);
params["page"] = 1;
params["resultsPerPage"] = 25;
var collection = new Model[modelName + "Collection"]({}, { searchParams: params });
params["Fields"] = collection.getSearchFields();
collection.getPage(params["page"], function (data) {
require(["app/views/SearchResults"], function (SearchResultsView) {
App.Router.navigate(modelName + "/search/results");
var view = new SearchResultsView({ collection: data, el: $(".content") });
view.delegateEvents();
});
});
return false;
});
和SearchResults.js
return BaseView.extend({
init: function () {
this.render();
},
render: function () {
var data = this.collection.convertToSearchResults();
this.$el.html(template(data));
return this;
}
});
问题是我第二次执行任何搜索(从 RecordSearch.js 调用 doSearch 函数)。一旦我执行第二次搜索,显示的数据就是属于我执行的上一次搜索的数据。 (例如,我进行名称搜索并且有效,然后进行公司搜索,但屏幕显示公司搜索结果,但随后很快被名称搜索结果替换)。
我的问题是
我怀疑我需要在重新使用视图之前调用一些清理代码。 backbone 应用程序中 运行 的正确位置在哪里。
我从 RecordSearch 视图中加载 SearchResults 视图的方式有什么问题吗? SearchResults 在我的路由器上没有路径,但它基本上是一种形式 post,所以我认为它不应该?
感谢任何帮助。
这个问题很常见,称为 Zombie Views。 Derick Bailey 在这里很好地解释了这个问题:http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/
然而不幸的是,如果不更改加载视图的方式,您无法简单地解决它。
因为您将它们加载到 RequireJS 模块中,这些模块会将其保留在本地 var 范围内,所以一旦路由被完全处理,您将失去对视图的引用。
为了解决这个问题,你需要将当前视图的引用保存在某个地方,然后在调用另一个视图之前适当地处理它,就像这样:
showView: function(view) {
this.currentView && this.currentView.remove();
this.currentView = view;
this.currentView.render();
$('#content').html(this.currentView.el);
}
在此处了解有关此解决方案的更多信息:http://tiagorg.com/talk-backbone-tricks-or-treats-html5devconf/#/6
我个人建议您采用一种解决方案来解决这个问题,例如 Marionette.js
它将通过提供每个基于 Backbone 的架构所缺失的空白来解决这个问题和许多其他问题。
我正在纠结何时销毁 backbone 视图。我知道我需要在某处破坏视图,但我不确定在哪里。
我在 router.js
routes: {
"names/search": "nameSearch",
"companies/search": "companySearch"
},
initialize: function(){
Backbone.history.start();
this.navigate("#/", true);
}
nameSearch: function () {
require(["app/views/RecordSearch"], function (RecordSearchView) {
var obj = {};
obj.Status = [utils.xlate("On Assignment"), utils.xlate("Candidate")];
var view = new RecordSearchView({ model: obj, el: $(".content") }, { "modelName": "Candidate" });
view.delegateEvents();
});
},
companySearch: function () {
require(["app/views/RecordSearch"], function (RecordSearchView) {
var view = new RecordSearchView({ model: {}, el: $(".content") }, { "modelName": "Company" });
view.delegateEvents();
});
}
然后在 RecordSearchView.js 中,我有以下函数,当用户单击搜索按钮时调用该函数
doSearch: function () {
require(["app/utils/SearchHelper", "app/models/" + modelName, "app/views/SearchResults"], function (SearchHelper, Model, SearchResultsView) {
var obj = $("#searchForm").serializeArray();
var params = SearchHelper.getQuery(obj);
params["page"] = 1;
params["resultsPerPage"] = 25;
var collection = new Model[modelName + "Collection"]({}, { searchParams: params });
params["Fields"] = collection.getSearchFields();
collection.getPage(params["page"], function (data) {
require(["app/views/SearchResults"], function (SearchResultsView) {
App.Router.navigate(modelName + "/search/results");
var view = new SearchResultsView({ collection: data, el: $(".content") });
view.delegateEvents();
});
});
return false;
});
和SearchResults.js
return BaseView.extend({
init: function () {
this.render();
},
render: function () {
var data = this.collection.convertToSearchResults();
this.$el.html(template(data));
return this;
}
});
问题是我第二次执行任何搜索(从 RecordSearch.js 调用 doSearch 函数)。一旦我执行第二次搜索,显示的数据就是属于我执行的上一次搜索的数据。 (例如,我进行名称搜索并且有效,然后进行公司搜索,但屏幕显示公司搜索结果,但随后很快被名称搜索结果替换)。 我的问题是
我怀疑我需要在重新使用视图之前调用一些清理代码。 backbone 应用程序中 运行 的正确位置在哪里。
我从 RecordSearch 视图中加载 SearchResults 视图的方式有什么问题吗? SearchResults 在我的路由器上没有路径,但它基本上是一种形式 post,所以我认为它不应该?
感谢任何帮助。
这个问题很常见,称为 Zombie Views。 Derick Bailey 在这里很好地解释了这个问题:http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/
然而不幸的是,如果不更改加载视图的方式,您无法简单地解决它。
因为您将它们加载到 RequireJS 模块中,这些模块会将其保留在本地 var 范围内,所以一旦路由被完全处理,您将失去对视图的引用。
为了解决这个问题,你需要将当前视图的引用保存在某个地方,然后在调用另一个视图之前适当地处理它,就像这样:
showView: function(view) {
this.currentView && this.currentView.remove();
this.currentView = view;
this.currentView.render();
$('#content').html(this.currentView.el);
}
在此处了解有关此解决方案的更多信息:http://tiagorg.com/talk-backbone-tricks-or-treats-html5devconf/#/6
我个人建议您采用一种解决方案来解决这个问题,例如 Marionette.js
它将通过提供每个基于 Backbone 的架构所缺失的空白来解决这个问题和许多其他问题。