【发布时间】:2013-08-28 10:27:27
【问题描述】:
我正在尝试编写一个咖啡脚本类,当从它构造一个新对象时,它会检查是否传递了一个 ID。如果是这样,请尝试查找匹配的文档并从中填充对象。如果没有传递 ID,则生成一个新 ID 并创建一个新文档。我正在使用 mongojs 连接到我的 mongodb。但是,当我从 TestObject 类创建一个新对象时,它会引发一个错误,即集合名称需要是一个字符串。我将@collection 设置为该类上的字符串,因此我控制台记录了@collection 属性及其未定义。这是怎么回事,我怎样才能使它工作?
class MongoObject
@collection
constructor: (id) ->
@_id = if typeof id is 'undefined' then require('node-uuid').v4() else id
@db = require('mongojs') config.mongo_server, [@collection]
@db[@collection].findOne
_id: @_id,
(error, story) ->
# Matching document found. Import data from document
if not error and story
for field, value of story
@[field] = value if field is not '_id'
# Matching document not found. Creating new one
if not error and not story
@db[@collection].save
id: @id
# Error occured
if error and not story
console.error error
return
class TestObject extends MongoObject
@collection = 'TestObjects'
constructor: (id) ->
super('TestObject')
编辑
重新阅读我的代码,很明显这是构造函数和 @collection 在 MongoObject 中未定义的问题。有没有更好的方法来做到这一点?我可以创建一个 setupDB 方法并在每个类的构造函数中调用它,该构造函数在超级调用之后扩展 MongoObject 但不是我所希望的。
编辑 2
我修改了我的代码。但是,我现在收到 constructor 未定义的错误。当我查看编译后的 javascript 时,它指向 MongoObject 代码顶部的 constructor;。奇怪的是,coffeescript 没有输入var constructor;,这通常会发生。我已经发布了翻译后的 javascript 仅供参考
咖啡脚本
class MongoObject
collection: undefined
constructor: (id) ->
@_id = if typeof id is 'undefined' then require('node-uuid').v4() else id
@db = require('mongojs') config.mongo_server, [@collection]
@db[@collection].findOne
_id: @_id,
(error, story) ->
# Matching document found. Import data from document
if not error and story
for field, value of story
@[field] = value if field is not '_id'
# Matching document not found. Creating new one
if not error and not story
@db[@collection].save
id: @id
# Error occured
if error and not story
console.error error
return
class TestObject extends MongoObject
collection = 'TestObjects'
constructor: (id) ->
super('TestObject')
Javascript
MongoObject = (function() {
MongoObject.prototype.collection = void 0;
function MongoObject(id) {
this._id = typeof id === 'undefined' ? require('node-uuid').v4() : id;
this.db = require('mongojs')(config.mongo_server, [this.collection]);
this.db[this.collection].findOne({
_id: this._id
}, function(error, story) {
var field, value;
if (!error && story) {
for (field in story) {
value = story[field];
if (field === !'_id') {
this[field] = value;
}
}
}
if (!error && !story) {
this.db[this.collection].save({
id: this.id
});
}
if (error && !story) {
console.error(error);
}
});
}
return MongoObject;
})();
TestObject = (function(_super) {
var collection;
__extends(TestObject, _super);
collection = 'TestObjects';
function TestObject(id) {
TestObject.__super__.constructor.call(this, 'TestObject');
}
return TestObject;
})(MongoObject);
编辑 3
根据我的 cmets 更新了我的代码。它说@constructor.collection在
@db[@constructor.collection].save
id: @id
我假设它是因为它在保存的回调函数中。前进一步,后退两步。
修改后的代码
class MongoObject
@collection
constructor: (id) ->
@_id = if typeof id is 'undefined' then require('node-uuid').v4() else id
@db = require('mongojs') config.mongo_server, [@constructor.collection]
@db[@constructor.collection].findOne
_id: @_id,
(error, story) ->
# Matching document found. Import data from document
if not error and story
for field, value of story
@[field] = value if field is not '_id'
# Matching document not found. Creating new one
if not error and not story
@db[@constructor.collection].save
id: @id
# Error occured
if error and not story
console.error error
return
class TestObject extends MongoObject
@collection: 'TestObjects'
constructor: (id) ->
super('TestObject')
【问题讨论】:
-
您希望
collection = 'TestObjects'做什么以及为什么要在构造函数中使用super('TestObjects')? -
super 被调用以运行其父类的构造函数。 super 在 python 中的使用方式相同。 arcturo.github.io/library/coffeescript/03_classes.html “在实践中,这与在 Ruby 或 Python 中调用 super 的效果完全相同,调用重写的继承函数。”我想先调用父构造函数逻辑
-
最终,我想要一个基类,其中包含 db 连接代码,并且每个扩展类都定义其集合名称,因此@db 将为每个类定义指向正确的集合。所以我不会一次又一次地重复代码。
-
我知道
super是做什么的,但你为什么用字符串调用它,为什么你说collection = ...而不是collection: ...?p = ...和p: ...的意思完全不同。如果你collection是一个类属性,那么说@collection: ...并在实例方法中将其引用为@constructor.collection。 -
嗯,基本结构有效 (jsfiddle.net/ambiguous/PTLVN),也许
findOne使用的@与您预期的不同,也许您应该使用=>来定义该回调。
标签: javascript mongodb coffeescript mongojs