Javascript Meteor-在对象列表中呈现所有者的名称

Javascript Meteor-在对象列表中呈现所有者的名称,javascript,mongodb,meteor,Javascript,Mongodb,Meteor,当我尝试查找对象的所有者时,发现一个“未找到对象”错误 我正在努力渲染。我正在浏览一系列视频剪辑,这些视频剪辑可以由用户更新或管理。当我登录时,代码工作正常,但当我尝试使用此代码并注销时,我会得到“队列任务中的异常:TypeError:无法读取Object.Template.video\u info.creatorName中未定义的属性'\u id' 我已尝试通过执行以下操作来调试: console.log(this.owner); var owner = Meteor.users.findOn

当我尝试查找对象的所有者时,发现一个“未找到对象”错误 我正在努力渲染。我正在浏览一系列视频剪辑,这些视频剪辑可以由用户更新或管理。当我登录时,代码工作正常,但当我尝试使用此代码并注销时,我会得到“队列任务中的异常:TypeError:无法读取Object.Template.video\u info.creatorName中未定义的属性'\u id'

我已尝试通过执行以下操作来调试:

console.log(this.owner);
var owner = Meteor.users.findOne(this.owner);
console.log(owner);
当我检查控制台日志时,我可以看到找到了正确的用户id,当我使用此id手动运行Meteor.users.findOne时,返回了一个用户对象。《流星》中的计时是否有什么奇怪的东西阻止了这一切

更新:如果我向模板creatorname函数添加了一个try…catch,那么会记录两个错误,但模板仍然呈现???这个模板似乎被调用了两次,一次是在它还没有准备好的时候,一次是在它准备好的时候。为什么会这样

try…catch块的示例:

  Template.video_info.creatorName = function () {
      try{
        var owner = Meteor.users.findOne(this.owner);
        if (owner._id === Meteor.userId())
          return "me";
        return displayName(owner);
      } catch (e){
        console.log(e);
      }
  };
在这一点以下的原始断开的代码

这是在我的HTML中:

<body>
  <div>
    {{> video_list}}
  </div>
</body>
<template name="video_list">
  <h1>Video List</h1>
  {{#each videos}}
    <ul>
      {{> video_info}}
    </ul>
  {{else}}
    No videos yet.
  {{/each}}
  <div class="footer">
    <button>Like!</button>
  </div>
</template>

<template name="video_info">
  <li class="video-list {{maybe_selected}}">
    <img src="{{image}}" />
    <div>
      <h3>{{title}}</h3>
      <p>{{description}}</p>
      <h4>{{creatorName}}</h4>
    </div>
  </li>
</template>
这在我的model.js中

Videos = new Meteor.Collection("videos");

Videos.allow({
  insert: function (userId, video) {
    return false; // no cowboy inserts -- use createParty method
  },
  update: function (userId, video, fields, modifier) {
    if (userId !== video.owner)
      return false; // not the owner

    var allowed = ["title", "description", "videoid", "image", "start"];
    if (_.difference(fields, allowed).length)
      return false; // tried to write to forbidden field

    // A good improvement would be to validate the type of the new
    // value of the field (and if a string, the length.) In the
    // future Meteor will have a schema system to makes that easier.
    return true;
  },
  remove: function (userId, video) {
    // You can only remove parties that you created and nobody is going to.
    return video.owner === userId; //&& attending(video) === 0;
  }
});

var NonEmptyString = Match.Where(function (x) {
  check(x, String);
  return x.length !== 0;
});

var NonEmptyNumber = Match.Where(function (x) {
  check(x, Number);
  return x.length !== 0;
});

createVideo = function (options) {
  var id = Random.id();
  Meteor.call('createVideo', _.extend({ _id: id }, options));
  return id;
};

Meteor.methods({
  // options should include: title, description, x, y, public
  createVideo: function (options) {
    check(options, {
      title: NonEmptyString,
      description: NonEmptyString,
      videoid: NonEmptyString,
      image:NonEmptyString,
      start: NonEmptyNumber,
      _id: Match.Optional(NonEmptyString)
    });

    if (options.title.length > 100)
      throw new Meteor.Error(413, "Title too long");
    if (options.description.length > 1000)
      throw new Meteor.Error(413, "Description too long");
    if (! this.userId)
      throw new Meteor.Error(403, "You must be logged in");

    var id = options._id || Random.id();
    Videos.insert({
      _id: id,
      owner: this.userId,
      videoid: options.videoid,
      image: options.image,
      start: options.start,
      title: options.title,
      description: options.description,
      public: !! options.public,
      invited: [],
      rsvps: []
    });
    return id;
  },

});

///////////////////////////////////////////////////////////////////////////////
// Users

displayName = function (user) {
  if (user.profile && user.profile.name)
    return user.profile.name;
  return user.emails[0].address;
};

var contactEmail = function (user) {
  if (user.emails && user.emails.length)
    return user.emails[0].address;
  if (user.services && user.services.facebook && user.services.facebook.email)
    return user.services.facebook.email;
  return null;
};

当您注销时,应用可能未将用户id发布到客户端。您可以尝试在服务器上调用find方法并返回用户。或者使用不同的键进行查询/

我想我已经找到了这个问题的解决方案。在阅读了Meteor中缓存的工作原理之后,我发现了订阅模型以及它与meteors minimongo的关系。失败的原因是,在第一次加载时,数据仍然缓存在minimongo中。我目前正在检查配置为检查用户数据是否已加载的帐户登录服务。我目前正在使用它,因为我找不到订阅Metor users服务的方法,但我猜测Accounts登录服务将依赖于Metor users集合。我当前的解决方案如下所示:

if(Accounts.loginServicesConfigured()){
  var owner = Meteor.users.findOne(this.owner);
  if (owner._id === Meteor.userId())
    return "me";
  return displayName(owner);
}
目前,这似乎工作正常。我仍在深入研究如何订阅这个用户服务。在搜索解决方案时,我发现了两个非常有用的重新协商


明确地推出用户ID。我使用它来标识对象列表(因此将有多个用户ID)。如果我把它包在一个try…catch块中,它就会运行。我认为这与手术的时机有关。
if(Accounts.loginServicesConfigured()){
  var owner = Meteor.users.findOne(this.owner);
  if (owner._id === Meteor.userId())
    return "me";
  return displayName(owner);
}