Я подозреваю, что способ обработки представлений в backbone.js является ошибочным, так как он создает «утечку памяти» ».Неоднократно создавая и уничтожая виды в Backbone.js или Marionette.js, не создавая «утечку памяти»
Существует вид, который постоянно переписывается другой копией самого себя. Новая копия связана с другой моделью.
Я создаю и добавляю представление к его родительскому виду, установив параметр el
при создании дочернего представления.
Странная вещь, которая происходит, заключается в том, что даже если новый вид визуализируется поверх старого представления, когда я нажимаю кнопку «,» появляется предупреждение для каждого дочернего элемента, который был отображен каждый, хотя кнопка они слушали, должны уходить, они отвечают на новую кнопку.
Я воспользовался быстрым решением, вызвав функцию на старом представлении, чтобы прекратить прослушивание событий до добавления нового представления. Но , что эта проблема существует вообще, говорит мне, что все старые представления висят вокруг и будут замедлять приложение с течением времени, если пользователь не обновит страницу достаточно часто.
var parent = new (Backbone.Marionette.ItemView.extend({
ui:{
child_container: '#child-container'
},
onRender: function(){
// Listen to outside event
...
}
on_Outside_Event: function(new_model){
// Quick fix prevents multiple alerts popping up for every child view when "button" is pressed
this.child_view.destroy_view();
// New child view is created and rendered on top of the one that was there before
this.child_view = childView({
el: this.ui.child_container, // <-- Is this the problem?
model: new_model
})
this.child_view.render();
}
}))();
var childView = Backbone.Marionette.ItemView.extend({
events:{
'click button': 'on_click_button'
},
on_click_button: function(){
// Alert pops up once for every view that was ever displayed.
alert('Button clicked');
},
// QUICK FIX
destroy_view: function(){
this.undelegateEvents();
}
})
В случае, если это полезно, вот скриншот фактического приложения. Справа - календарь назначений. Детский вид проблемы - вид индивидуального назначения, который пользователь хочет видеть, находится слева.
При нажатии на кнопку «Отменить назначение», эта функция вызывается для каждого назначения, который каждый отображается в этой области, хотя я слушаю случае не используя: events:{ 'click #cancel-button': 'on_button_click'}
Ни одна из других кнопок, взаимодействия, а также другие элементы управления имеют такую же проблему, я предполагаю, потому что все остальные на самом деле живут взгляды, дети зрения ребенка назначения и не в представлении ребенка назначения сам
Возможное исправление ?
Немного искал, делает ли это исправление адекватным?
Обычно, я думаю, что функции removeData().unbind();
и remove()
называются непосредственно на this.$el
, но это не работает здесь, я думаю, потому что я добавил мнение ребенка с помощью опции el
, когда она была создана (el: this.ui.child_container
)
var childView = Backbone.Marionette.ItemView.extend({
...
// REAL FIX
destroy_view: function(){
this.undelegateEvents();
this.$el.children().removeData().unbind();
this.$el.children().remove();
}
Когда я впервые начал использовать марионетка, я Раскладка несколько раз, но я не думаю, что я очень хорошо понимал их.Это приложение большое, существует множество уровней родительских представлений и представлений для детей. Есть ли времена, когда нормально встраивать макеты? Если я правильно понимаю, обычно не рекомендуется повторно отображать макет (я почти никогда не пересматриваю виды в любом случае)? Когда вы будете использовать ItemView, а не макет? Благодаря! –
Макеты очень полезны, и тот факт, что они являются гнездовыми, является одной из вещей, которые делают их отличными. В документе о марионетке упоминается, что они гнездятся по своему усмотрению. Но вы правы, вам следует избегать повторного рендеринга большого «дерева» вложенных макетов. Но есть много способов избежать этого, как правило, просто привязывая взгляды вашего ребенка к их модели или к тому, что меняется, и заставляя их повторно отображать самих себя. Например, в вашем примере, почему бы вам просто не обновить модель дочернего представления с данными новой модели, заставив ее повторно отобразить? Вместо того, чтобы заменить его новым? – Robin
Я не обновляю модель детского вида с новой информацией, потому что есть только одна копия каждой модели. Одна модель иногда стоит за несколькими видами. В этом примере вид детализации встречи на левой стороне и вид назначения в календаре с правой стороны используют ту же модель. Так, например, при изменении «start_time» назначения в подробном представлении позиция назначения в календаре будет фактически изменяться по мере того, как пользователь будет вводить данные. В будущем я хотел бы добавить push-обновления моделей с сервера. Когда это произойдет, все представления будут обновляться. –