0

Я борюсь с тем, когда нужно разрушать представления о скелетах. Я знаю, что мне нужно что-то разрушить, но я не знаю, где.
У меня есть следующий код в 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; 
    } 
}); 

проблема заключается в второй раз, когда я выполнить любой поиск (вызов функции doSearch от RecordSearch.js). Как только я выполняю второй поиск, отображаются данные, принадлежащие предыдущему поиску, который я выполнил. (Например, я выполняю поиск по имени, и он работает, затем выполняйте поиск компании, но на экране отображаются результаты поиска компании, но затем быстро заменяется результатами поиска по имени). Мои вопросы

  1. Я подозреваю, что нужно вызвать некоторый код очистки на представлении до его повторного использования. Где это место в базовом приложении для запуска этого приложения.

  2. Есть ли что-то не так с тем, как я загружаю SearchResults из вида RecordSearch? SearchResults не имеет пути на моем маршрутизаторе, но в основном это сообщение формы, поэтому я предполагаю, что это не так?

Любая помощь приветствуется.

+0

Вы правы, что вам следует обрабатывать жизненные циклы просмотра, но, учитывая вашу настройку, это не кажется вашей проблемой. Вы выполняете 'this. $ El.html()' между представлением рендеринга, поэтому старые представления не должны появляться повторно. Копать немного глубже, как перейти от результата поиска к новому поиску? – seebiscuit

+1

У вас есть несколько элементов на странице с классом контента? Кажется странным, что * все * получает визуализацию в том же элементе «.conent». – seebiscuit

+0

@Печа, спасибо, я понимаю, что вы имеете в виду.Я не понимал, как базовый контент передается в элемент представления. Это было проблемой в моем коде, но главной проблемой была проблема с зомби-представлением, предложенная ниже. – Ronnie

ответ

1

Эта проблема довольно распространена и известна как зомби-представления. 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

Он будет обрабатывать это и довольно много других вопросов, путем предоставления СУИ петь пробелы каждой архитектуры на базе базовой архитектуры.

+0

Ваша точка зрения очень важна, и я запомню ваше предположение, что OP должен пойти с Marionette. Однако он не сообщает об общей жалобе на зомби: несколько запусков событий. Поэтому я думаю, что они могут быть другими недостатками с его кодом. – seebiscuit

+0

RequireJs и его само по себе не проблема. RequestJs callbacks по-прежнему уважают закрытие функции, и к этому закрытию всегда можно получить доступ к другому контексту. Я бы не предлагал переписать весь код. – seebiscuit

+1

Мои проблемы были вызваны зомби-представлениями, и я пошел с подобным подходом. У меня есть один класс, который обрабатывает всю визуализацию каждого вида, поэтому они всегда могут быть правильно уничтожены. – Ronnie