我一直在摸索为什么这段代码会在某些时候起作用,但不是全部(或者至少在大多数情况下)。我发现它实际上确实在某些时候在浏览器中显示正确的内容,但奇怪的是,有几天我会回到相同的代码,运行服务器(按照正常情况)并在加载时页面将在控制台中收到错误:TypeError: 'undefined' is not an object (evaluating 'Session.get('x').html')
(当我收到该错误时,控制台中的下一行有时会显示Error
- 引用err
对象,有时会读取Object
- 引用data
对象!?)。
我显然在Meteor中遗漏了一些关于会话变量的内容并且必须滥用它们?我希望有经验的人能指出我正确的方向。
先谢谢你的帮助!
这是我的虚拟代码:
/client/del.html
<head>
<title>del</title>
</head>
<body>
{{> hello}}
</body>
<template name="hello">
Hello World!
<div class="helloButton">{{{greeting}}}</div>
</template>
我的客户端javascript文件是:
/client/del.js
Meteor.call('foo', 300, function(err, data) {
err ? console.log(err) : console.log(data);
Session.set('x', data);
});
Template.hello.events = {
'click div.helloButton' : function(evt) {
if ( Session.get('x').answer.toString() === evt.target.innerHTML ) {
console.log('yay!');
}
}
};
Template.hello.greeting = function() {
return Session.get('x').html;
};
我的服务器端javascript是:
/server/svr.js
Meteor.methods({
doubled: function(num) {
return num * 2;
},
foo: function(lmt) {
var count = lmt,
result = {};
for ( var i = 0; i < lmt; i++ ) {
count++;
}
count = Meteor.call('doubled', count);
result.html = "<em>" + count + "</em>";
result.answer = count;
return result;
}
});
答案 0 :(得分:1)
我认为,当客户端首次启动时,会话变量还没有设置好。因此,Session.get('x')
将返回undefined
,直到您的方法调用(foo
)返回,这几乎肯定不会在模板首次绘制之前发生。
然而,之后它会在会话中,所以一旦刷新,事情可能会正常。
答案是在尝试访问变量之前检查它是否为undefined
。例如:
Template.hello.greeting = function() {
if (Session.get('x')) return Session.get('x').html;
};
答案 1 :(得分:1)
Meteor的seven principles之一是:
延迟补偿。在客户端上,使用预取和模型模拟使其看起来像是与数据库的零延迟连接。
由于存在延迟,您的客户端将首先尝试根据客户端连接时的数据绘制布局。然后它将进行呼叫,然后它将根据呼叫进行更新。有时呼叫可能能够快速响应以便同时绘制。
现在有可能没有设置变量,它会在那种情况下抛出异常,从而中断执行(因为调用堆栈中的函数不会继续运行)。
有两种可能的解决方案:
使用时检查变量是否已设置。
return Session.get('x') ? Session.get('x').html : '';
通过将变量设置在脚本顶部,确保变量具有初始值。
Session.set('x', { html = '', answer = ''});
另一种方法是在呼叫响应后添加模板。
Meteor.call('foo', 300, function(err, data) {
Session.set('x', data);
$('#page').html(Meteor.ui.render(function() {
return Template.someName();
}));
});