2

我一直在摸索为什么这段代码在某些时候会起作用,但不是全部(或至少在大多数情况下)。我发现它确实有时会在浏览器中显示正确的内容,但奇怪的是,有几天我会回到相同的代码,运行服务器(正常)并加载页面将在控制台中收到错误:TypeError: 'undefined' is not an object (evaluating 'Session.get('x').html')

(当我收到该错误时,有时控制台中的下一行会读取Error- 引用err对象,而其他时候会读取Object- 引用data对象!?)。

我显然在 Meteor 中遗漏了一些关于 Session 变量的东西,并且一定是在滥用它们?我希望有经验的人能指出我正确的方向。

谢谢,提前提供任何帮助!

这是我的虚拟代码:

/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;

  }

});
4

2 回答 2

1

我认为只是客户端首次启动时尚未设置会话变量。所以Session.get('x')会返回undefined,直到你的方法调用(foo)返回,这几乎肯定不会在模板第一次绘制之前发生。

然而,在那之后它将在会话中,所以一旦你刷新,事情可能会正常运行。

答案是undefined在尝试访问变量之前检查它是否是。例如:

Template.hello.greeting = function() {
  if (Session.get('x')) return Session.get('x').html;
};
于 2012-06-02T03:34:00.030 回答
1

Meteor的七大原则之一是:

延迟补偿。在客户端上,使用预取和模型模拟使其看起来像与数据库的零延迟连接。

由于存在延迟,您的客户端将首先尝试根据客户端连接时的数据绘制布局。然后它将进行调用,然后根据调用进行更新。有时,呼叫可能能够足够快地响应以同时被绘制。

由于现在有可能不设置变量,它会在那种情况下抛出异常并因此中断执行(因为调用堆栈中的函数将不会继续运行)。

对此有两种可能的解决方案:

  1. 使用时检查变量是否已设置。

    return Session.get('x') ? Session.get('x').html : '';

  2. 通过在脚本顶部设置变量来确保变量具有初始值。

    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();
    }));
});
于 2012-06-02T23:03:34.000 回答