Вот пара возможностей.
1. Централизованные: хранить ClosedTune
объекты в TuneBook
например
хранить ссылку на каждый ClosedTune
в tune_book.tunes
. Как вы заполняете tune_book.tunes
зависит от вас; так как вы упомянули метод сумматора на TuneBook
, вот что я проиллюстрировал ниже.
В обработчике TuneBook
событий, извлекать ClosedTune
из tune_book.tunes
, используя что-то вроде атрибута id
мишени события в качестве ключа. Затем вызовите обработчик Tune
или ClosedTune
.
http://jsfiddle.net/p5QMT/1/
var Tune = Backbone.View.extend({
className: "tune",
click_handler: function (event) {
event.preventDefault();
console.log(this.id + " clicked");
},
render: function() {
this.$el.html(
'<a href="" class="button">' + this.id + '</a>'
);
return this;
}
});
var ClosedTune = Tune.extend({});
var OpenTune = Tune.extend({
events: {
"click .button" : 'click_handler'
}
});
var TuneBook = Backbone.View.extend({
events: {
"click .tune .button" : 'click_handler'
},
click_handler: function (event) {
var tune = this.options.tunes[
$(event.target).closest(".tune").attr('id')
];
tune.click_handler(event);
},
add_tune: function (tune) {
this.options.tunes[tune.id] = tune;
this.$el.append(tune.render().el);
},
render: function() {
$("body").append(this.el);
return this;
}
});
var tune_book = new TuneBook({
tunes: {}
});
[1, 2, 3].forEach(function (number) {
tune_book.add_tune(new ClosedTune({
id: "closed-tune-" + number
}));
});
tune_book.render();
var open_tune = new OpenTune({
id: "open-tune-1"
});
$("body").append(open_tune.render().el);
2. Децентрализованная: связать объект вида с объектом DOM с помощью jQuery.data()
При создании ClosedTune
, сохраните ссылку на него, например, this.$el.data('view_object', this)
.
В случае прослушивания прослушивания, найдите ClosedTune
, например. $(event.target).data('view_object')
.
Вы можете использовать тот же самый точный обработчик для ClosedTune
(в TuneBook
) и OpenTune
, если вы хотите.
http://jsfiddle.net/jQZNF/1/
var Tune = Backbone.View.extend({
className: "tune",
initialize: function (options) {
this.$el.data('view_object', this);
},
click_handler: function (event) {
event.preventDefault();
var tune =
$(event.target).closest(".tune").data('view_object');
console.log(tune.id + " clicked");
},
render: function() {
this.$el.html(
'<a href="" class="button">' + this.id + '</a>'
);
return this;
}
});
var ClosedTune = Tune.extend({
initialize: function (options) {
this.constructor.__super__.initialize.call(this, options);
}
});
var OpenTune = Tune.extend({
events: {
"click .button" : 'click_handler'
}
});
var TuneBook = Backbone.View.extend({
events: {
"click .tune .button": Tune.prototype.click_handler
},
add_tune: function (tune) {
this.$el.append(tune.render().el);
},
render: function() {
$("body").append(this.el);
return this;
}
});
var tune_book = new TuneBook({
tunes: {}
});
[1, 2, 3].forEach(function (number) {
tune_book.add_tune(new ClosedTune({
id: "closed-tune-" + number
}));
});
tune_book.render();
var open_tune = new OpenTune({
id: "open-tune-1"
});
$("body").append(open_tune.render().el);
Ответ на комментарий
я считал вариант 1, но решил против него, как у меня уже есть коллекция настраивать модели в tunebook и не хотел другой объект I» d необходимо сохранить в синхронизации
Я думаю, это зависит от того, какое домашнее хозяйство/синхронизация вы чувствуете необходимость и почему.
(например, в TuneModel.remove() мне нужно, чтобы удалить вид из списка tunebook о виде ... наверное нужно событие, чтобы сделать это, так что это событие только решение начинает выглядеть более привлекательным).
Почему вы чувствуете, что «нужно удалить представление из списка tunebook по взглядам»? (Я не предлагаю, чтобы вы этого не сделали, просто спросите, почему вы хотите.) Так как вы делаете, как вы думаете, подход @ ggozad отличается в этом отношении?
Оба метода хранят ClosedTune
объектов в экземпляре TuneBook
. В технике @ ggozad это просто скрыто за абстракцией, которая, возможно, делает ее менее очевидной для вас.
В моем примере они хранятся в простом объекте JS (tune_book.tunes
). В @ ggozad они хранятся в структуре _callbacks
, используемой Backbone.Events
.
Добавление ClosedTune
:
1.
this.options.tunes[tune.id] = tune;
2.
this.on('buttonClick:' + tune.id, tune.handler, tune);
Если вы хотите избавиться от ClosedTune
(скажем, удалить его из документа с tune.remove()
и вы хотите, чтобы объект вида полностью исчез), используя подход @ ggozad, оставит осиротую ссылку на ClosedTune
в tune_book._callbacks
, если не выполнять такую же домашнем хозяйстве, что будет иметь смысл с подходом, я предложил:
1.
delete this.options.tunes[tune.id];
tune.remove();
2.
this.off("buttonClick:" + tune.id);
tune.remove();
Первая строка каждого примера необязательно - в зависимости от того, хотите ли вы очистить объекты ClosedTune
или нет.
Вариант 2 - это более или менее то, что я делаю прямо сейчас, но (по другим причинам). Я также сохраняю модель как атрибут данных в представлении. $ El, и я не могу не чувствовать, что есть должен быть лучшим способом, чем хранить ссылки повсюду.
Ну, это в конечном итоге сводится к вашему предпочтению, как структурировать вещи. Если вы предпочитаете хранить объекты вида более централизованным образом, их можно сохранить в экземпляре TuneBook
вместо использования jQuery.data
. См. № 1: Централизованный.
Так или иначе вы храните ссылки на ClosedTune
объектов: с помощью jQuery.data
, или в простом объекте в TuneBook
, или в _callbacks
в TuneBook
.
Если вам нравится подход @ ggozad по причинам, которые вы понимаете, идите на это, но это не волшебство. Поскольку он представлен здесь, я не уверен, что преимущество должно обеспечиваться дополнительным уровнем абстракции по сравнению с более простой версией, представленной в № 1. Если есть какое-то преимущество, не стесняйтесь заполнять меня.
Если события будут выполнены обработчиками в модели 'Tune', то вы хотите сделать обход' ChildView -> ParentView -> Model' .. вы можете выполнить 'Model.handler' непосредственно из' ChildView' .. В другой руке вы можете использовать «Модель» в качестве посланника: вы можете изменить состояние модели из ChildView и позволить ParentView прослушивать эту модификацию. – fguillen
@fguillen. Менее эффективно связывать события (возможно, я должен понимать, что я имею в виду события DOM, а не настраиваемые события Backbone) на узел DOM каждого дочернего представления, а не только один раз на узел DOM родительского представления. На таблице 300 строк, сгенерированной моей производительностью приложения, заметно вяло при привязке непосредственно к каждой строке. Мне нужен «ParentView» -> [childView] -> childModel' – wheresrhys