Вложенные представления в представлениях в магистрали js
Я работаю с backbone.js, создавая сложные отношения вида, и мне интересно, есть ли какие-либо проблемы с точки зрения производительности javascript, чтобы сделать что-то похожее на это:
var viewOne = Backbone.View.extend({
tagName : 'li',
initialize : function() {
this.v2 = new viewTwo({parent:this});
},
clickHideOne : function() {
$(this.el).removeClass('selected');
}
});
var viewTwo = Backbone.View.extend({
tagName : 'a',
initialize : function() {
this.bind('click', this.clickHide, this);
},
clickHide(){
$(this.el).removeClass('selected');
this.options.parent.clickHideOne();
}
});
Если это очень простой пример круговой ссылки между двумя представлениями, чтобы события в одном представлении легко распространяли цепочку представлений или поддерживали любые ссылки на объекты в родительских представлениях. Существуют ли ситуации, когда это будет проблемой, особенно в отношении потенциальных утечек с ссылками на элементы DOM в IE7 +, или есть еще одна рекомендуемая передовая практика для ссылок на родительские представления.
Кроме того, я понимаю, что я мог бы просто сделать $(this.el).parent('li'). removeClass ('selected'); in viewTwo, это не точка... это просто очень простой пример вопроса о круговой ссылке.
Ответы
Ответ 1
Наличие родительского представления, ответственного за дочерние представления, не является плохой идеей и является довольно распространенным сценарием в магистрали. Проблема, которую я вижу с приведенным выше кодом, заключается в том, что представление child имеет представление о его родительском представлении. Я бы предложил использовать пользовательские события в viewTwo и привязать viewOne к этим событиям, а затем ответить соответствующим образом.
Это довольно легко с использованием метода trigger() и метода bind().
Ответ 2
Циркулярные ссылки - плохая идея. Также не очень хорошая практика, как сказал Кайл, что детское представление имеет ясную ссылку на его родительское представление. Явные ссылки должны отображаться только в иерархии представлений. То есть, это нормально и типично для родительского представления иметь явные ссылки на все его дочерние представления и вызывать методы дочерних представлений для взаимодействия с ними. (См. Backbone.Subviews mixin для каждого способа создания и управления дочерними представлениями). Однако наилучшая практика инкапсуляции диктует, что представление никогда не должно иметь явных ссылок или напрямую обращаться непосредственно к методам своих братьев и сестер или его родителей.
Чтобы общаться с родными братьями или родителями, у вас есть три варианта, о которых я знаю:
-
Используйте view.trigger()
, чтобы вызвать событие на дочернем представлении (или родстве), а затем родительский (или родной) прослушивать это событие с помощью view.listenTo()
. Этот подход работает, но начинает разрушаться, когда вы хотите, чтобы дочерний вид связывался с его дедушкой и т.д. Кроме того, вы создаете ненужные явные зависимости, если вы используете этот подход с братьями и сестрами.
-
Вы можете использовать Backbone.Courier, который является плагином, который позволяет легко раздувать события в иерархии представлений. Для связи между представлениями одного и того же брата один из братьев взбирает событие до родителя, а потом родитель вызывает метод другого брата напрямую.
-
Вы можете использовать агрегатор событий, чтобы действовать как промежуточный объект между дочерним и родительским, или между братьями и сестрами. Таким образом, эти представления могут связываться через агрегатор без явных ссылок друг на друга. Однако для этого подхода требуются глобальные объекты агрегатора, а также допускается пересечение неявных зависимостей, которые могут стать труднодоступными, поскольку число просмотров растет.
Ответ 3
Вложение - хороший способ поддерживать иерархические представления для написания поддерживаемого кода для сложных пользовательских интерфейсов. В простом примере проблемы с производительностью практически отсутствуют, но в более сложных ситуациях вам нужно иметь в виду, насколько глубока ваша вложенность.
Например, использование сложных ячеек-рендеринга неправильно в сетке из тысяч строк может сделать ваше приложение непригодным. В таких случаях обычно можно сделать умную оптимизацию, например. используя рендереры только для видимых ячеек сетки.