我之前读过很多与组合优于继承有关的内容,我完全认同这个概念,并在我的代码中经常使用这个原则。但是在我的日常工作中,继承常常出现在视图中,我很难看到如何实现更加组合式的方案(由于我在日常工作中使用的是Backbone框架,这也让问题变得更加困难)。当我想要利用现有的所有Backbone视图功能并在其基础上添加一些额外的功能时,这些问题就会出现。
以下是一个假设性的示例:我们有一个电子商务类型的页面,其中包含多个“Product”视图,每个视图代表特定产品的可选项集合。
以下是一个假设性的示例:我们有一个电子商务类型的页面,其中包含多个“Product”视图,每个视图代表特定产品的可选项集合。
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);
假设我们想展示一些需要提示访问者确认的产品(比如由于保险原因,这个特定的产品必须与保险一起销售,所以当用户将其添加到购物篮时,我们需要提示用户):
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);
有没有更可组合的方法编写这个代码?或者这种情况下通过继承分离是正确的做法?