Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 了解Meteor何时重新计算我的模板助手_Javascript_Mongodb_Templates_Meteor - Fatal编程技术网

Javascript 了解Meteor何时重新计算我的模板助手

Javascript 了解Meteor何时重新计算我的模板助手,javascript,mongodb,templates,meteor,Javascript,Mongodb,Templates,Meteor,我正试着用我的头脑去思考流星的反应性。我知道当模板中引用的被动数据源发生更改时,它会重新呈现页面。我还了解什么是反应源(会话、MongoDB游标等) 我很难理解的是所有这些对模板助手的“幕后”调用。除了反应性之外,似乎还有其他原因导致它们 特别是,在下面的代码中,我有一个friendRequests帮助程序,在单独访问/friends页面时,它会被重新计算两次有时三次。如果重新计算两次,DB查询将成功!如果重新计算三次,则第一个数据库访问(出于某些奇怪的原因)无法查询数据库,而后两个则成功 这是

我正试着用我的头脑去思考流星的反应性。我知道当模板中引用的被动数据源发生更改时,它会重新呈现页面。我还了解什么是反应源(会话、MongoDB游标等)

我很难理解的是所有这些对模板助手的“幕后”调用。除了反应性之外,似乎还有其他原因导致它们

特别是,在下面的代码中,我有一个
friendRequests
帮助程序,在单独访问
/friends
页面时,它会被重新计算两次有时三次。如果重新计算两次,DB查询将成功!如果重新计算三次,则第一个数据库访问(出于某些奇怪的原因)无法查询数据库,而后两个则成功

这是数据库失败时的堆栈跟踪:

// NOTE: imsolonely is one of the users that should be returned in the friendRequests
imsolonely's public key: undefined
debug.js:41 Exception in template helper: TypeError: Cannot read property 'profile' of undefined
    at Object.Utils.getPublicKeyByUsername (http://localhost:3000/lib/utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:79:22)
    at Object.Utils.getFingerprintByUsername (http://localhost:3000/lib/utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:88:24)
    at http://localhost:3000/client/friends.js?dbec4a7537c9d0abf56a74489824969cb7baadfe:25:35
    at Array.forEach (native)
    at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
    at Object.Template.friendRequests.helpers.friendRequests (http://localhost:3000/client/friends.js?dbec4a7537c9d0abf56a74489824969cb7baadfe:22:7)
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2693:16
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:1602:16
    at Object.Spacebars.dot (http://localhost:3000/packages/spacebars.js?3c496d2950151d744a8574297b46d2763a123bdf:231:13)
    at http://localhost:3000/client/template.friends.js?a2da726f6dad1aaecfdedfe216aa3378fff938b5:24:37
utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:78 imsolonely's public key: {"profile":{"publicKey":"0404b4880129edc1ea2652dd1eff1c8728269874b9b0ace02cc90edcb449c3f3d716c2f8b79a5fe5695d52cd85aed228f977073538625e8e71f1cfd764766669b1"},"_id":"sXjzt7YHA8KTyAib5"}
utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:78 imsolonely's public key: {"profile":{"publicKey":"0404b4880129edc1ea2652dd1eff1c8728269874b9b0ace02cc90edcb449c3f3d716c2f8b79a5fe5695d52cd85aed228f977073538625e8e71f1cfd764766669b1"},"_id":"sXjzt7YHA8KTyAib5"}
这也发生在我的许多(或全部,不确定)助手身上。它们在需要时被调用,因为用户未登录(并且模板未呈现,因此不应重新计算助手)

下面是一些代码:

client/friends.js

Template.friendRequests.helpers({
friendRequests:函数(){
//问题1:在我登录之后但在我完全登录之前,模板会被调用
//所以我需要这个电话。
如果(!Meteor.user())
返回Utils.notLoggedInErrorMsg;
//问题2:模板被调用了三次。第一次DB查询失败
//好像DB行不存在。接下来的2次它成功了。但它应该只存在
//打过一次电话。
var reqs=Friends.getFriendRequests(Utils.me());
_.每个(需求、功能(要素、it、列表){
检查(element.initiator,String);
//获取用户的指纹
element.fingerprint=Utils.getFingerprintByUsername(element.initiator);
});
退货要求;
},  
});
client/friends.html


{{>friendRequests}
{{>searchForm}
我的朋友们
    {{{各位朋友}
  • {{this}}
  • {{/每个}}
好友请求 {{#如果friendRequests.length} 今天有人很受欢迎

    {{{#每个friendRequests}
  • 带有指纹的{{initiator}}{{fingerprint}}在{date}向您发送了一个请求 {{/每个}}
{{else} 对不起,现在没人喜欢你

{{/if}
lib/utils.js

Utils={
// ...
//其他东西
// ...
//@以字符串形式返回十六进制编码的公钥
getPublicKeyByUsername:函数(用户名){
var user=Meteor.users.findOne({username:username},{fields:{'profile.publicKey':1}});
log(用户名+'\'的公钥:'+EJSON.stringify(用户));
var pubKey=user.profile.publicKey;
返回公钥;
},  
//注意:尚未使用,我在需要时直接使用了CryptoUtils函数
//  
//@以十六进制编码字符串的形式返回指纹
getFingerprintByUsername:函数(用户名){
var pubKey=Utils.getPublicKeyByUsername(用户名);
var fingerprint=CryptoUtils.getPublicKeyFingerprint(pubKey);
返回指纹;
},  
notLoggedInErrorMsg:“流星是愚蠢的,在我没有登录的时候叫这个。”,
}
如果重要的话,我正在使用
iron:router
1.0.3包重定向到
/friends
URL

如果您能澄清为什么
/friendsrequests
帮助程序在看不见的情况下被重新计算,为什么在刷新
/friends
页面时被重新计算两次、三次而不是一次,我们将不胜感激

谢谢,,
Alin

一般来说,您应该期望您的助手会接到多次电话。如果在用户登录时呈现模板,而不等待数据发布,则助手可能会运行:

  • 当请求路线时
  • 当用户完成登录时
  • Friends
    数据首次到达客户端时
  • 当其他
    朋友
    数据到达或被修改时
  • 要解决第一个问题,您可以检查Meteor.user()| | Meteor.loggin(),就像我在对的回答中所做的那样(请注意,自从我回答之后,路由器API已经更改,但它应该让您知道该怎么做)


    你的第二个问题的答案可以在我的帖子上找到。简言之,您不能假设数据已到达客户端,因此您需要在呈现模板之前检查其存在性,或者需要在路由器中明确订阅。

    事实证明,my
    waitOn
    hook中存在错误。我没有返回任何东西,我只是进行
    Meteor.subscribe()
    调用,而不是返回它们的数组。以下是修复DB异常的方法:

    Router.configure({
    layoutTemplate:“主布局”,
    loadingTemplate:“正在加载”,
    waitOn:函数(){
    返回[
    Meteor.subscribe('userData'),
    Meteor.subscribe(“allUserData”),
    Meteor.subscribe('UserProfiles'),
    ];
    },
    });
    
    对于未定义的
    Meteor.user()
    ,我仍然没有一个好的解决方案。或者这也解决了问题


    PS:谢谢@DavidWeldon帮我缩小范围

    因此,我有一个
    Router.configure()
    设置默认布局,并为我所有代码中需要的
    Meteor.subscribe
    调用设置一个
    waitOn
    。我还有一个
    路由器.onBeforeAction
    ,可以重定向到具有不同布局的登录页面。我真的不喜欢我必须为
    Meteor.user()
    签入几十个模板,而这些模板在
    Meteor.user()==false
    时甚至没有呈现(或者至少不应该呈现)。另外,即使我要到处检查,我会返回什么?我猜