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 函数)。一旦我执行第二次搜索,显示的数据就是属于我执行的上一次搜索的数据。 (例如,我进行名称搜索并且有效,然后进行公司搜索,但屏幕显示公司搜索结果,但随后很快被名称搜索结果替换)。 我的问题是

  1. 我怀疑我需要在重新使用视图之前调用一些清理代码。 backbone 应用程序中 运行 的正确位置在哪里。

  2. 我从 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 的架构所缺失的空白来解决这个问题和许多其他问题。