Я использую Backbone вместе с jQuery и requireJS. Я хотел бы знать, какой хороший способ сделать кешированные объекты jQuery доступными для нескольких видов в Backbone. Скажем, у меня есть pageView, homeView, aboutView и contactView.
Во всех этих представлениях я манипулирую DOM, и в настоящий момент мне нужно создавать каждый раз новую оболочку jQuery для следующих элементов DOM:.side-left,.side-right,.page-left и.page-right.
Какой лучший способ только обернуть эти элементы один раз, а не всегда создавать новый экземпляр?
Первое намерение состояло в том, чтобы добавить все модели в коллекцию и кэшировать элементы DOM. К сожалению, не все мои взгляды имеют модель. Как мне с этим справиться?
Спасибо заранее за любые предложения.
В приведенном ниже коде показано, как я сейчас решаю его для одного вида. Но у других нет доступа к этому, поскольку они не используют одну и ту же модель.
PageModel.js
define([
'underscore',
'backbone'
], function(_, Backbone) {
var PageModel = Backbone.Model.extend({
defaults: {
leftSide: $('#splitlayout div.intro > div.side-left'),
rightSide: $('#splitlayout div.intro > div.side-right'),
pageLeft: $('#splitlayout div.page-left'),
pageRight: $('#splitlayout div.page-right')
}
});
return PageModel;
});
PageView.js
define([
'jquery',
'underscore',
'backbone',
'global',
'models/video/VideoModel',
'views/video/VideoView'
], function($, _, Backbone, Global, VideoModel, VideoView){
var PageView = Backbone.View.extend({
el: $("#splitlayout"),
events: {
'click .intro-content': 'resetLayout',
'click .back': 'backToIntro'
},
render: function(){
this.$el.addClass('reset-layout');
this.model.get('pageLeft').on(Global.transEndEventName, this.onEndTransFn);
this.model.get('pageRight').on(Global.transEndEventName, this.onEndTransFn);
},
initialize: function() {
_.bindAll(this);
this.videoModel = new VideoModel();
this.VideoView = new VideoView({model: this.videoModel});
this.render();
},
onEndTransFn: function() {
this.$el.addClass('reset-layout');
$('html, body').scrollTop = 0;
},
backToIntro: function(ev) {
ev.preventDefault();
var dir = $(ev.currentTarget).hasClass('back-right') ? 'left' : 'right';
this.$el.removeClass('open-' + dir);
this.$el.addClass('close-' + dir);
},
resetLayout: function(ev) {
var layoutClass = $(ev.currentTarget).parent().hasClass('side-left') ? 'open-left' : 'open-right';
this.$el.addClass(layoutClass)
this.$el.removeClass('close-right close-left reset-layout');
}
});
return PageView;
});
Я собираюсь немного обойти ваш вопрос и сказать, просто не надо. IMO-представление должно нести ответственность за связанный с ним элемент и его детей (будь то больше видов или разметки). Если вы хотите установить связь между представлениями, вы должны использовать шину событий (ниже используется базовая Backbone
deafult, но вы можете определить свои собственные). Поэтому для вашего дела я бы сделал следующее:
var PageView = Backbone.View.extend({
...
initialize: function() {
this.listenTo(Backbone, Global.transEndEventName, this.onEndTransFn);
...
},
то любой вид генерирует событие,
var VideoView = Backbone.View.extend({
...
events: {
'click div.page-left': 'eventFired',
},
eventFired : function(){
Backbone.trigger(Global.transEndEventName);
}
Вы действительно не показываете отношения своих взглядов, так что это всего лишь пример экстраполяции.