我是Node的新手,我正在尝试使用ExpressJS(http://expressjs.com/)创建一个MVC应用程序。我在GitHub上使用与MVC示例(https://github.com/visionmedia/express/tree/master/examples/mvc)相同的文件夹结构。
在我的控制器文件夹中,我有2个文件夹:main和system。我想要的是在/controllers/system/index.js中定义一个基本控制器,并让/controllers/main/index.js继承系统控制器。每个其他模块都会扩展系统并覆盖一些函数来生成页面。
在另一个教程中,我找到了以下代码。
Base.js
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' });
}
});
如果没有Underscore的扩展功能,你怎么做? Express是否有内置的方法来扩展模块?我正在使用doT.js进行模板化,所以我不想为一个函数包含另一个大型库。
谢谢!
编辑:必须进行一些更改才能从dc5中获取基本代码。系统工作,但主要我在继承调用上得到这个错误:
util.js:555
ctor.prototype = Object.create(superCtor.prototype, {
^
TypeError: Object prototype may only be an Object or null
at Function.create (native)
at Object.exports.inherits (util.js:555:27)
/controllers/system/index.js:
var util = require( 'util' ),
system = { };
system.index = function( req, res, next ) {
res.render( 'main' );
};
module.exports = system;
/controllers/main/index.js:
var util = require( 'util' ),
system = require( './../system/index' ),
main = { };
util.inherits( main, system );
module.exports = main;
答案 0 :(得分:9)
您可以将util.inherits用于您所描述的内容。它不是_.extend()
的替代品,但上述示例所需的只是直接继承。
用法:util.inherits(constructor, superConstructor)
base.js:
var util = require('util');
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) {…}
或者标准的JS继承模式:
base.js:
function Base() {…}
Base.prototype.run = function(req,res,next) {…}
module.exports = Base;
home.js:
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;
主:
var util = require('util');
var System = require("../system/");
function Main() {
// Makes sure the System constructor is run
System.apply(this, arguments);
this.name = "Main";
}
util.inherits(Main, System);
Main.prototype.run = function(req,res,next) {
this.sayHello();
console.log('calling ==> overrideMe');
this.overrideMe();
console.log('calling ==> noOverride');
this.noOverride();
next ? next() : "";
}
Main.prototype.overrideMe = function() {
console.log('Main.overrideMe');
}
module.exports = Main;
根目录中的app.js - 一个简化的快速服务器:
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时,必须将{{1}}方法绑定到该实例。有关详细信息,请参阅:MDN .bind documentation。
答案 1 :(得分:0)
为避免复杂的配置和变通方法,使用ZinkyJS,它提供了一种更好的方法来使模块继承成为可能。