我是JavaScript和流星框架的新用户,试图理解基本概念。首先,我想将一个文档添加到一个没有重复条目的集合中。
this.addRole = function(roleName){
console.log(MongoRoles.find({name: roleName}).count());
if(!MongoRoles.find({name: roleName}).count())
MongoRoles.insert({name: roleName});
}
此代码在服务器和客户端上调用。客户端上的日志消息告诉我集合中没有条目。即使我多次刷新页面。
在服务器上,重复的条目将输入到集合中。我不知道为什么。可能我不明白关键概念。有人能指出我吗,拜托?
修改-1: 不,不再安装autopublish和insecure了。但我已经发布了MongoRoles集合(服务器端)并订阅了它(客户端)。此外,我为插入(客户端)创建了一个允许规则。
修改-2:
非常感谢我向我展示了流星方法的方法,但是我希望能够在没有服务器端方法的情况下做到这一点。让我们说出来用于学术目的。 ; - )
刚写了一个小例子:
客户端:
Posts = new Mongo.Collection("posts");
Posts.insert({title: "title-1"});
console.log(Posts.find().count());
服务器:
Posts = new Mongo.Collection("posts");
Meteor.publish(null, function () {
return Posts.find()
})
Posts.allow({
insert: function(){return true}
})
如果我通过“meteor mongo”检查服务器数据库'它告诉我我的客户端代码的每个插入都保存在那里。
客户端上的日志告诉我' 1计数'每次刷新页面。但我期望两者都一样。我做错了什么?
修改-3:
我回到原来的角色榜样(对不起)。只是觉得我明白了,但我仍然无能为力。如果我检查变量' roleCount',则会始终响应0。如何将正确的值加载到我的变量中?在插入集合之前检查文档是否存在的最佳方法是什么?猜猜.find()也是异步的吗?如果是这样,我怎么能同步?如果我做对了,我必须等待值(同步),因为我真的继续它。
共享环境(客户端和服务器):
Roles = new Mongo.Collection("jaqua_roles");
Roles.allow({
insert: function(){return true}
})
var Role = function(){
this.addRole = function(roleName){
var roleCount = Roles.find({name: roleName}).count();
console.log(roleCount);
if(roleCount === 0){
Roles.insert({name: roleName}, function(error, result){
try{
console.log("Success: " + result);
var roleCount = Roles.find({name: roleName}).count();
console.log(roleCount);
} catch(error){
}
});
}
};
this.deleteRole = function(){
};
}
role = new Role();
role.addRole('test-role');
仅限服务器:
Meteor.publish(null, function () {
return Roles.find()
})
答案 0 :(得分:1)
Meteor的insert/update/remove
方法(客户端)不是一个好主意。太多潜在的安全隐患,需要花费很多心思和时间才能真正修补任何漏洞。 Further reading这里。
我也想知道你从哪里打来addRole
。假设它只是从客户端触发,我会这样做:
this.addRole = function(roleName){
var roleCount = MongoRoles.find({name: roleName}).count();
console.log(roleCount);
if (roleCount === 0) {
Meteor.call('insertRole', roleName, function (error, result) {
if (error) {
// check error.error and error.reason (if I'm remembering right)
} else {
// Success!
}
});
}
}
我如何修改此代码以及原因:
roleCount
变量,这样就可以避免两次调用MongoRoles.find()
,这样效率很低,并且会消耗不需要的资源(CPU,磁盘I / O等)。存储一次,然后更好地引用变量。if (!count)
之类的操作。使用if (count === 0)
更清晰,并显示您引用了一个数字。像if (!xyz)
这样的语句会让人觉得这是一个布尔值(真/假)值。===
,除非您有意执行松散的相等操作。 Read more就此而言。if
和其他块使用开/闭花括号,即使它只包含一行代码。这只是一个很好的做法,所以如果您决定稍后添加另一行,则不必将其包装在大括号中。只是一个很好的练习。Meteor.method('insertRole', function (roleName) {
check(roleName, String);
try {
// Any security checks, such as logged-in user, validating roleName, etc
MongoRoles.insert({name: roleName});
} catch (error) {
// error handling. just throw an error from here and handle it on client
if (badThing) {
throw new Meteor.Error('bad-thing', 'A bad thing happened.');
}
}
});
希望这会有所帮助。这完全不是我的头脑,根本没有测试。但是,当涉及到数据库操作时,它应该让您更好地了解改进的结构。
您的代码看起来不错,除了几个问题:
Posts
两次,不要这样做。创建一个文件,例如/lib/collections/posts.js
,并将Mongo.Collection
的声明和实例化放在那里。然后它将在客户端和服务器上执行。console.log
可能会返回错误或零,因为Posts.insert
在客户端是异步的。请尝试以下方法:
Posts.insert({title: "title-1"}, function (error, result) {
console.log(Posts.find().count());
});