我的JS被组织成视图模型和服务。这些服务主要关注AJAX调用,而我的viewModels描述了它们用于的视图。
我现在有两个视图模型 - StoreViewModel和MyStoreViewModel。在每一项中,我都有以下内容:
function MyStoreVm(model) {
var self = this;
self.doThis = function(){
// do stuff
self.doThat();
};
}
然后:
function StoreVm(model) {
var self = this;
self.doThis = function(){
// do stuff
self.doThat();
};
}
我来自C#背景 - 通常我会在这种情况下使用继承。如何通过让它们从第三个共享模块继承来消除两个不同模块/视图模型之间的代码重复?
更多细节:这些是在MVC视图中使用的,我根据商店是否为MyStore进行了敲除绑定:
@if (!Model.IsMyStore) {
<script type="text/javascript">
$(document).ready(ko.applyBindings(new StoreVm(@Html.Raw(JsonConvert.SerializeObject(Model, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() })))));
</script>
} else if (Model.IsMyStore) {
<script type="text/javascript">
$(document).ready(ko.applyBindings(new MyStoreVm(@Html.Raw(JsonConvert.SerializeObject(Model, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() }).Sanitize()))));
</script>
}
更新
我查看了下面的一些建议,但似乎没有一个对我的新手技能来说足够干净和简单。我尝试了以下似乎有效:
function BaseStore(model){
self.doThis = function(){
// do stuff
self.doThat();
};
// and a whole lot of other shared code
}
function StoreVm(model) {
var storeVm = new BaseStoreVm(model)
var self = storeVm;
self.isolatedFunctionForGenericStores = function(){stuff}
// other stuff for only this type
return storeVm;
}
function MyStoreVm(model) {
var myStoreVm = new BaseStoreVm(model)
var self = myStoreVm;
self.isolatedFunctionForMyStore = function(){stuff}
// other stuff for only this type
return myStoreVm;
}
这种方法有什么问题吗?
答案 0 :(得分:2)
如果您有两个需要从同一父级继承的子类型,则可以执行以下操作:
function Parent( foo ) {
this.foo = foo;
}
Parent.prototype.method = function() {
console.log( this.foo );
};
function Child1() {
Parent.call( this, "bar" );
}
Child1.prototype = Object.create( Parent.prototype );
Child1.prototype.constructor = Child1;
function Child2() {
Parent.call( this, "qux" );
}
Child2.prototype = Object.create( Parent.prototype );
Child2.prototype.constructor = Child2;
var parent = new Parent("blah");
var child1 = new Child1();
var child2 = new Child2();
parent.method(); // => "blah"
child1.method(); // => "bar"
child2.method(); // => "qux"
答案 1 :(得分:0)
首先,您应该了解JavaScript
如何实现继承。 JavaScript
是一种基于原型的语言,不包含类语句,例如C#
中的语句。相反,它使用函数作为类(没有类,只有对象)
所以我们这里有 对象 继承自其他 对象 (现在你可能需要得到一些咖啡)。
因此,JavaScript
并没有为您提供C#
中的继承和多态性的全部功能。
如果你想知道在JS中实现继承的方法:
回到您的问题,我认为您可能需要实施 The Factory Pattern 。所以你的js代码可能是这样的:
function MyStoreVm(model) {
var self = this;
self.doThis = function() {
// do stuff
self.doThat();
};
}
function StoreVm(model) {
var self = this;
self.doThis = function() {
// do stuff
self.doThat();
};
}
// Define factory object that create your proper store object
// StoreFactory takes the model as input.
// You can change it to accept seconf parameter that define class type
function StoreFactory() {
this.classType == "MyStoreVm"; // default value
this.createStore = function(model) {
if (model.IsMyStore === true)
this.classType = MyStoreVm;
else
this.classType = StoreVm;
return new this.classType(model);
}
}
然后在你的MVC视图中:
$(document).ready(function() {
var mystoreFactory = new StoreFactory();
ko.applyBindings(mystoreFactory.createStore((@Html.Raw(JsonConvert.SerializeObject(Model, new JsonSerializerSettings() {
ContractResolver = new CamelCasePropertyNamesContractResolver()
})))));
});
答案 2 :(得分:0)
结帐Klass.js。虽然这与创建自己的原型和继承方法基本相同,但它很好用。这也是AMD意识到的。
// base class
var Store = klass(function() {
var self = this;
// add properties here
}).methods({
doThis: function () {
// do this
},
doThat: function () {
// do that
}
});
return Store;
// create the first constructor
var myStoreVm = Store.extend(function () {
// super class is called
}).methods({
doThis: function(){
this.supr(); // call Store.doThis
// some other code
}
});
return myStoreVm;
// create the second constructor
var storeVm = Store.extend(function () {
// super class is called
}).methods({
doThis: function(){
// override Store.doThis with my own code
}
});
return storeVm;