我正在使用 Durandal 构建一个应用程序,并且我需要跨视图模型共享一些功能。
我有 5 个屏幕要构建,它们实际上都是相同的屏幕,除了在激活函数中它们将调用不同的 api 端点,否则视图和视图模型将是相同的。
我应该遵循一种模式来正确地构建它以促进代码重用吗?
我正在使用 Durandal 构建一个应用程序,并且我需要跨视图模型共享一些功能。
我有 5 个屏幕要构建,它们实际上都是相同的屏幕,除了在激活函数中它们将调用不同的 api 端点,否则视图和视图模型将是相同的。
我应该遵循一种模式来正确地构建它以促进代码重用吗?
如果视图和视图模型除了调用不同的 api 操作之外是相同的,那么仅将参数作为路由的一部分呢?然后在激活功能中,您可以打开参数。可以指定路由值,以便您的 url 是相关的,例如 [ http://site/page/subtype],其中 subtype 是参数(而不是使用数值)
关于继承,根据您需要的功能,有很多方法可以进行 JavaScript 继承,这可能有点令人困惑。base2和Prototype等库提供了一些功能齐全的继承模型。 John Resig 也有一个我已经成功使用的继承模型。
一般来说,当涉及到 JS 继承时,我更喜欢坚持更简单的解决方案。如果您需要几乎完整的继承功能集,那么可以考虑使用这些库。如果您只关心从基类访问一组属性和函数,您可能只需将视图模型定义为函数,并将函数的原型替换为所需的基类即可。有关继承的详细信息,请参阅Mozilla 的开发人员文档。
这是一个示例:
//viewModelBase
define(function (require) {
"use strict";
function _ctor() {
var baseProperty = "Hello from base";
function baseFunction() {
console.log("Hello from base function");
}
//exports
this.baseProperty = baseProperty;
this.baseFunction = baseFunction;
};
//return an instance of the view model (singleton)
return new _ctor();
});
//view model that inherits from viewModelBase
define(function (require) {
"use strict";
function _ctor() {
var property1 = "my property value";
function activate() {
//add start up logic here, and return true, false, or a promise()
return true;
}
//exports
this.activate = activate;
this.property1 = property1;
};
//set the "base"
var _base = require("viewModelBase");
_ctor.prototype = _base;
_ctor.prototype.constructor = _ctor;
//return an instance of the view model (singleton)
return new _ctor();
});
请记住这个例子所有的结果都是一个有效的单例(即你只会得到相同的实例,无论你需要多少次()它)
如果您想要一个瞬态(非单例),只需返回 _ctor。然后,您需要在 require() 之后实例化一个新实例。
还有一点需要注意的是,一般来说,函数应该在原型上定义,而不是在构造函数本身内。有关原因的更多信息,请参阅此链接。因为这个例子只产生了一个实例,所以这是一个有争议的问题,所以函数在构造函数中以提高可读性以及访问私有变量和函数的能力。