Javascript 如何在ExpressJS中创建可扩展控制器
我是Node的新手,我正在尝试用ExpressJS()创建一个MVC应用程序。我使用的文件夹结构与GitHub上的MVC示例()相同 在我的控制器文件夹中,我有两个文件夹:主文件夹和系统文件夹。我希望在/controllers/system/index.js中定义一个基本控制器,并让/controllers/main/index.js继承系统控制器。其他每个模块都将扩展系统并覆盖一些函数以生成页面 在另一个教程中,我发现了以下代码 Base.jsJavascript 如何在ExpressJS中创建可扩展控制器,javascript,node.js,express,dot.js,Javascript,Node.js,Express,Dot.js,我是Node的新手,我正在尝试用ExpressJS()创建一个MVC应用程序。我使用的文件夹结构与GitHub上的MVC示例()相同 在我的控制器文件夹中,我有两个文件夹:主文件夹和系统文件夹。我希望在/controllers/system/index.js中定义一个基本控制器,并让/controllers/main/index.js继承系统控制器。其他每个模块都将扩展系统并覆盖一些函数以生成页面 在另一个教程中,我发现了以下代码 Base.js var _ = require("undersc
var _ = require("underscore");
module.exports = {
name: "base",
extend: function(child) {
return _.extend({}, this, child);
},
run: function(req, res, next) {
}
};
Home.js
var BaseController = require("./Base"),
View = require("../views/Base"),
model = new (require("../models/ContentModel"));
module.exports = BaseController.extend({
name: "Home",
content: null,
run: function(req, res, next) {
model.setDB(req.db);
var self = this;
this.getContent(function() {
var v = new View(res, 'home');
v.render(self.content);
})
},
getContent: function(callback) {
var self = this;
this.content = {};
model.getlist(function(err, records) {
if(records.length > 0) {
self.content.bannerTitle = records[0].title;
self.content.bannerText = records[0].text;
}
model.getlist(function(err, records) {
var blogArticles = '';
if(records.length > 0) {
var to = records.length < 5 ? records.length : 4;
for(var i=0; i<to; i++) {
var record = records[i];
blogArticles += '\
<div class="item">\
<img src="' + record.picture + '" alt="" />\
<a href="/blog/' + record.ID + '">' + record.title + '</a>\
</div>\
';
}
}
self.content.blogArticles = blogArticles;
callback();
}, { type: 'blog' });
}, { type: 'home' });
}
});
/控制器/system/index.js:
var util = require( 'util' ),
system = { };
system.index = function( req, res, next ) {
res.render( 'main' );
};
module.exports = system;
var util = require( 'util' ),
system = require( './../system/index' ),
main = { };
util.inherits( main, system );
module.exports = main;
/控制器/main/index.js:
var util = require( 'util' ),
system = { };
system.index = function( req, res, next ) {
res.render( 'main' );
};
module.exports = system;
var util = require( 'util' ),
system = require( './../system/index' ),
main = { };
util.inherits( main, system );
module.exports = main;
您可以使用您所描述的内容。它并不是\uuu0.extend()
的替代品,但上面的示例所需要的只是直接继承
用法:util.inherits(构造函数、超级构造函数)
base.js:
var util = require('util');
function Base() {…}
Base.prototype.run = function(req,res,next) {…}
module.exports = Base;
function Base() {…}
Base.prototype.run = function(req,res,next) {…}
module.exports = Base;
home.js:
var util = require('util');
var BaseController = require("./base");
function Home() {…}
util.inherits(home, BaseController);
Home.prototype.run = function(req,res,next) {…}
var BaseController = require("./base");
function Home() {
BaseController.apply(this, arguments);
}
Home.prototype = Object.create(BaseController.prototype);
Home.prototype.run = function(req,res,next) {…}
或标准JS继承模式:
base.js:
var util = require('util');
function Base() {…}
Base.prototype.run = function(req,res,next) {…}
module.exports = Base;
function Base() {…}
Base.prototype.run = function(req,res,next) {…}
module.exports = Base;
home.js:
var util = require('util');
var BaseController = require("./base");
function Home() {…}
util.inherits(home, BaseController);
Home.prototype.run = function(req,res,next) {…}
var BaseController = require("./base");
function Home() {
BaseController.apply(this, arguments);
}
Home.prototype = Object.create(BaseController.prototype);
Home.prototype.run = function(req,res,next) {…}
根据问题中更新的示例,模块应如下所示: 系统:
var util = require('util');
function System() {
this.txt = "hello from ";
this.name = "System";
}
System.prototype.sayHello = function() {
console.log(this.txt + this.name);
}
System.prototype.run = function(req,res,next) {
this.sayHello();
console.log('calling ==> overrideMe');
this.overrideMe();
console.log('calling ==> noOverride');
this.noOverride();
next ? next() : "";
}
System.prototype.overrideMe = function() {
console.log('System.overrideMe');
}
System.prototype.noOverride = function() {
console.log('System.noOverride');
}
module.exports = System;
主要内容:
根目录中的app.js-简化的express服务器:
var System = require('./controllers/system');
var Main = require('./controllers/main');
var express = require('express');
var path = require('path');
var http = require('http');
var app = express();
var server;
var system = new System();
var main = new Main();
app.configure(function() {
"use strict";
app.set('port', process.env.PORT || 3000, '127.0.0.1');
app.use(system.run.bind(system));
app.use(main.run.bind(main));
app.use(app.router);
//app.use(express.compress());
app.use(express.static(path.join(__dirname, '..', 'public'), {redirect: false}));
app.use(express.static(path.join("/Users/dave/personal/playground/yo"), {redirect: false}));
});
server = http.createServer(app);
server.listen(app.get('port'), function() {
"use strict";
console.log("Express server listening on port " + app.get('port'));
});
从浏览器访问:http://localhost:3000/
控制台输出:
Express server listening on port 3000
hello from System
calling ==> overrideMe
System.overrideMe
calling ==> noOverride
System.noOverride
hello from Main
calling ==> overrideMe
Main.overrideMe
calling ==> noOverride
System.noOverride
重要
由于此示例使用
System
和Main
的实例提供路由,因此将run
方法传递给express时必须将其绑定到实例。请参阅:了解更多信息。为了避免复杂的配置和解决方法,请使用,它提供了一种更好的方法,使模块继承成为可能。感谢您的响应,我尝试了代码,但我遇到了以下错误:util.js:555 ctor.prototype=Object.create(supercor.prototype,{^TypeError:对象原型可能只是一个对象或null谢谢你的详细回复,很遗憾我无法让它工作。如果在系统中我做module.exports=system(函数未实例化),那么在main中我可以做module.exports=new main()我没有收到任何错误,但导出的方法不适用于我链接的MVC示例中的动态路由。如果在系统中,我创建了一个实例(module.exports=new system())该模块将按预期工作,但当我尝试在main中扩展它时,我得到了相同的对象。创建错误。我似乎无法进行扩展,并且仍然让两个控制器将方法传递给模块。导出?有什么想法吗?@Jonathan我已将该示例更新为基本的express应用程序,以演示如何将run
方法用作路由最重要的是使用bind()
以在express调用运行
路由时提供适当的上下文。在这种情况下,system和main都是简单对象。util.inherits
的两个参数都需要是构造函数。我不确定是否遵循。我尝试放置main.constructor、main.prototype和main.prototype.constructor,但它们都不起作用系统被初始化为{},这是一个类型为object
的空对象。我将在我的答案中添加一个使用相同名称和目录结构的更新。