Я много читал в прошлом о способности к наследованию, и я полностью продаю эту концепцию и использую эту Принцип много в моем коде.Композиция над наследованием, что является более удобным способом добавления дополнительных функций к представлению, не прибегая к наследованию
Однако я столкнулся с проблемами в повседневной работе, когда наследование имеет тенденцию ползать в представлениях, и я изо всех сил пытаюсь понять, как я могу реализовать что-то более сложное (не помогает тот факт, что я использую Backbone в моем изо дня в день). Это, как правило, когда я хочу использовать все функции существующего представления Backbone, добавляя некоторые дополнительные функции сверху.
Возьмите этот гипотетический пример, где мы имеем страницу типа электронной коммерции с множественным Product
зрения, каждый представляющий коллекцию basketable опций для конкретного продукта:
var ProductView = (function(Backbone, JST) {
'use strict';
return Backbone.View.extend({
className: 'product',
template: JST['application/templates/product']
initialize: function(options) {
this.options = options || {};
this.collection.fetch();
this.listenTo(this.collection, 'loaded', this.render);
},
render: function() {
this.$el.html(
this.template(this.collection)
);
return this;
},
}, {
create: function(el) {
var endpoint = '/api/options/' + el.getAttribute('data-basket-id') + '/' + el.getAttribute('data-product-id');
new ProductView({
el: el,
collection: new ProductCollection(null, { url: endpoint })
});
}
});
})(Backbone, JST);
Say мы тогда хотим показать некоторые продукты, которые требуют посетитель будет предложено ввести в окне подтверждения (скажем, по страховым причинам, данный продукт должен продаваться со страховкой, так что мы должны предложить пользователю об этом, когда они добавить его в свою корзину):
var InsuranceProductView = (function (_, ProductView) {
'use strict';
return ProductView.extend({
consentTemplate: JST['application/templates/product/insurance_consent'],
initialize: function (options) {
this.listenTo(this.model, 'change:selected', function (model) {
if (!model.get('selected')) {
this.removeMessage()
}
});
ProductView.prototype.initialize.apply(this, arguments);
},
events: function() {
return _.extend({}, ProductView.prototype.events, {
'change input[type=radio]': function() {
this.el.parentElement.appendChild(this.consentTemplate());
},
'change .insurance__accept': function() {
ProductView.prototype.onChange.apply(this);
},
});
},
removeMessage: function() {
var message = this.el.parentElement.querySelector('.insurance__consent');
message.parentNode.removeChild(message);
},
});
})(_, ProductView);
Есть ли более сложный способ написать это? Или это ситуация, когда нужно покончить с наследством?