Javascript 继承DurandalJS中的公共函数
我正在寻找一种更好的方法来处理DurandalJS应用程序中的继承,从Javascript 继承DurandalJS中的公共函数,javascript,inheritance,prototype,durandal,Javascript,Inheritance,Prototype,Durandal,我正在寻找一种更好的方法来处理DurandalJS应用程序中的继承,从baseViewModel.js到其他页面。以下是我当前的应用程序结构: baseViewModel.js 主壳体 第一组外壳 第1页 第2页 第2组外壳 第1页 第2页 所有这些页面都共享一些通用功能(baseViewModel.js),例如: isLoading:检查页面上是否加载了内容的可观察对象 isValid:检查表单是否有效 添加和删除项目的afterAdd和beforeRemove效果 表单的键
baseViewModel.js
到其他页面。以下是我当前的应用程序结构:
- baseViewModel.js
- 主壳体
- 第一组外壳
- 第1页
- 第2页
- 第2组外壳
- 第1页
- 第2页
- 第一组外壳
- isLoading:检查页面上是否加载了内容的可观察对象
- isValid:检查表单是否有效
- 添加和删除项目的afterAdd和beforeRemove效果
- 表单的键盘快捷键
- 模板切换功能
- 等
baseViewModel.js
中的所有内容都声明为self.
,self是对窗口对象的引用,例如:
self.showElement = function(elem) {
if (elem.nodeType === 1) $(elem).hide().fadeIn();
}
self.fadeRemove = function(elem) {
if (elem.nodeType === 1) $(elem).fadeOut(500, function() { $(elem).remove(); });
}
baseViewModel.js
一次,然后通过应用程序访问它,如下所示:
<tbody data-bind="foreach: { data: dataArr, afterAdd: showElement, beforeRemove: fadeRemove }">
baseViewModel.js
中创建了一个Base
函数,并将其作为单例返回。然后在其中一页中,我做了:
define(['durandal/app', 'jquery', 'knockout', 'baseViewModel'], function (app, $, ko, base) {
var Page1 = function() {};
Page1.prototype = base;
return Page1;
});
在Base中声明的函数在Page1的视图和视图模型中工作得很好,但问题是我需要它们在与Page1一起加载的所有模块中工作。这包括:
- 第1组外壳视图(在基座内有一个按钮可激活功能)
- 主壳体视图(根据底座内部可观察到的
值,加载条可见)isLoading
*。prototype=base代码>在每个视图模型中
那么,有没有更好的方法来处理继承呢?如果没有,有没有办法只声明一次基并将其应用于所有子页面
谢谢 我将原型继承与工厂方法结合使用,到目前为止,它似乎工作得很好。我只想要简单的继承,所以这不是像某些继承库那样的全功能继承方法
正如PW所建议的,我确实将我的基本视图模型包装在一个requireJs模块中
这是一个简化的代码示例,但它应该是功能性的。如果没有道理,请告诉我,我可以详细说明
基本视图模型
define(function (require) {
"use strict";
function ViewModelBase() {
//this is the activate function that Durandal will call
function activate() {
//call activate on derived vm
if (this.onActivate) {
return this.onActivate.apply(this, arguments);
} else {
return true;
}
}
//validate view model and display all remaining errors
function validate() {
// passing 'this' so that the viewmodel instance is evaluated at the time it's needed
return validation.validateViewModel(this); //this is knockout validation
}
//exports
this.activate = activate;
this.validate = validate;
};
//return the constructor (non-singleton)
return ViewModelBase;
});
define(function (require) {
"use strict";
var factory = require("fusion/factory");
var HomeViewModel = factory.createViewModel(function () {
var __viewModel = this; //use __viewModel variable to access this view model instance.
function onActivate() {
//add application startup logic here
//access public functions on the base view model like this:
__viewModel.validate();
return true;
}
this.onActivate = onActivate;
});
//returns the constructor (non-singleton)
return HomeViewModel;
//to return a singleton instead, do this
return new HomeViewModel();
}); // END :: define statement
工厂
define(function (require) {
"use strict";
return {
createViewModel: function (ctor) {
ctor.prototype = new (require("view-model-base"))();
ctor.prototype.constructor = ctor;
return ctor;
}
};
});
派生视图模型
define(function (require) {
"use strict";
function ViewModelBase() {
//this is the activate function that Durandal will call
function activate() {
//call activate on derived vm
if (this.onActivate) {
return this.onActivate.apply(this, arguments);
} else {
return true;
}
}
//validate view model and display all remaining errors
function validate() {
// passing 'this' so that the viewmodel instance is evaluated at the time it's needed
return validation.validateViewModel(this); //this is knockout validation
}
//exports
this.activate = activate;
this.validate = validate;
};
//return the constructor (non-singleton)
return ViewModelBase;
});
define(function (require) {
"use strict";
var factory = require("fusion/factory");
var HomeViewModel = factory.createViewModel(function () {
var __viewModel = this; //use __viewModel variable to access this view model instance.
function onActivate() {
//add application startup logic here
//access public functions on the base view model like this:
__viewModel.validate();
return true;
}
this.onActivate = onActivate;
});
//returns the constructor (non-singleton)
return HomeViewModel;
//to return a singleton instead, do this
return new HomeViewModel();
}); // END :: define statement
mixins是模块间共享功能时可能考虑的另一种模式。
请注意@Joseph Gabriel的答案绝对正确。对于某些用例来说,mixin只是一个更轻的替代品,但它们不提供任何类型的继承
编辑已更新示例和实时版本,以更好地展示需要放置的位置,以便a)公共b)共享c)在所有页面
实例中唯一
common.js
页面视图模型
页面视图
混合样品
现场版可在以下网址获得:似乎原型设计是一种方法。您是否考虑过在require.js的配置中注册base,以便它可以始终与诸如baseVM.whatever()之类的常用词一起使用?我不知道它是否能帮你找到你想要的东西,所以就把它作为评论扔进去。你看过打字稿了吗?它使JavaScription中的继承变得很容易,谢谢您的回答。我注意到,在视图模型中声明Page1之后,如果我只使用Page1.prototype=new(require(“视图模型库”)()
和Page1.prototype.constructor=Page1
,我似乎会得到相同的结果。我遗漏了什么区别吗?不,我想是一样的。我正在为一个企业开发一个框架,工厂为我提供了另一个抽象层,以防我以后需要更改技术或添加功能
/*globals define */
define(['durandal/app', 'jquery', 'knockout', './common'], function( app, $, ko, common ) {
"use strict";
var Page = function() {
this.uniqueObservable = ko.observable('uniqueObservable: Page property. Click me... ');
};
// Extend the prototype with the common properties and
// `extend` it further with shared properties
$.extend(true, Page.prototype, common, {
sharedObservable : ko.observable('sharedObservable: mixed in after common. Click me...')
});
return Page;
});
<div>
<h1>mixin sample</h1>
<ul class="unstyled ">
<li data-bind="text: commonObservable, click: fadeRemove"></li>
<li data-bind="text: sharedObservable, click: fadeRemove"></li>
<li data-bind="text: uniqueObservable, click: fadeRemove"></li>
</ul>
</div>