我正在改造一个基于淘汰赛的网络应用程序,它将有不同的主题。主题之间的差异可以在视图和功能中。某些功能特定于主题,而其他功能可能在2个或更多主题中很常见,但不是全部。还有其他功能可以是所有主题。
目标是拥有一个框架,通过删除代码重复,具有适当的结构,松散的有限功能和改进的可测试性来提供可维护性。
我正在设想包含可重用功能的组件。我称之为“base”组件。可以通过配置参数配置这些组件。这些组件并非特定于任何主题。
我想建立一个允许的框架:
为了实现上述要求,我使用了Knockout 3.2 +中提供的components支持
我能够处理特定于主题的视图,但无法找到扩展主题中“基础”组件的方法。
欢迎提出任何想法。
我创建了两个KO组件:“base-menu”和“menu”。
“base-menu”组件是:
define("base-menu", ['knockout'], function (ko) {
function ViewModel(params) {
// this parameter should be configurable in theme
var name = params.name || "No Name";
this.name = ko.observable(name);
this.dispose = function () {
console.log("base dispose");
}
};
return {
viewModel: ViewModel,
template: '<h2><span data-bind="text: name"></span> Settings in BASE</h2>'
};
});
“menu”组件是:
// TODO: this component should "inherit" from base-menu, so that it has a "name" observable
define("menu", ['knockout'], function (ko) {
function ViewModel(params) {
this.sections = params.sections || [];
this.selectedSection = ko.observable();
this.dispose = function () {
// TODO: this should call base-menu's dispose function
console.log("theme dispose");
}
};
return {
viewModel: ViewModel,
template: '<h2><span data-bind="text: name"></span> Settings in THEME</h2><ul class="nav nav-pills" data-bind="foreach: sections"><li data-bind="css: { active: $parent.selectedSection() === $data }"><a href="#" data-bind="text: $data, click: $parent.selectedSection"></a></li></ul>'
};
});
“menu”组件应该从“base-menu”组件“继承”,以便它具有“name”可观察。
我怎样才能做到这一点?
可编辑示例在JSFiddle
处给出答案 0 :(得分:0)
你可以通过使用原型继承来实现这一点 - 虽然它有点难看,特别是没有super
概念来调用基本方法。您可以考虑使用ES2015并通过Babel进行转换,以便获得更清晰的类语法。
// TODO: this component should "inherit" from base-menu, so that it has a "name" observable
define("menu", ['knockout', 'base-menu'], function (ko, baseMenu) {
function ViewModel(params) {
baseMenu.viewModel.call(this, params);
this.sections = params.sections || [];
this.selectedSection = ko.observable();
this.dispose = function () {
baseMenu.viewModel.prototype.dispose.call(this);
// TODO: this should call base-menu's dispose function
console.log("theme dispose");
}
};
ViewModel.prototype = new baseMenu.viewModel();
return {
viewModel: ViewModel,
template: '<h2><span data-bind="text: name"></span> Settings in THEME</h2><ul class="nav nav-pills" data-bind="foreach: sections"><li data-bind="css: { active: $parent.selectedSection() === $data }"><a href="#" data-bind="text: $data, click: $parent.selectedSection"></a></li></ul>'
};
});
// menu.{js|ts|es6}
// Same thing in ES2015/ES6/TypeScript
import ko, { observable } from 'knockout;
import { viewModel as BaseMenu } from 'base-menu';
export class viewModel extends BaseMenu {
constructor(params) {
super(params);
this.sections = params.sections || [];
this.selectedSection = observable();
}
dispose() {
super.dispose();
}
};
export var template = 'Your template here';