流星 - 在列表对象中呈现所有者的名称

Meteor - rendering the name of the owner in a list objects

本文关键字:所有者 列表 对象 流星      更新时间:2023-09-26

当我尝试查找对象的所有者时,我收到一个找不到对象错误我正在尝试渲染。我正在循环浏览一组视频剪辑,这些剪辑可以由用户更新或管理。当我登录时,代码工作正常,但是当我尝试使用它并注销时,我得到"排队任务中的异常:类型错误:无法读取 Object.Template.video_info.creatorName 处未定义的属性'_id' "

我试图通过这样做来调试它:

console.log(this.owner);
var owner = Meteor.users.findOne(this.owner);
console.log(owner);

当我检查控制台日志时,我可以看到找到了正确的用户ID,当我使用此ID手动运行Meteor.users.findOne时,我返回了一个用户对象。流星的时间有什么奇怪的地方阻止了这一点吗?

更新:如果我添加尝试...捕获到模板创建者名称函数,然后记录 2 个错误,但模板仍然呈现... ???似乎这个模板被调用了两次,一次是在它还没有准备好的时候,一次是一次。为什么会这样。

尝试示例...捕获块:

  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>

这是我的客户端.js

Meteor.subscribe("videos");
if (Meteor.isClient) {
  Template.video_list.videos = function() {
    return Videos.find({}, {sort: {title: 1}});
  };
  Template.video_list.events = {
    'click button': function(){
      Videos.update(Session.get('session_video'),{$inc: {likes: 1}});
    }
  }
  Template.video_info.maybe_selected = function() {
    return Session.equals('session_video', this._id) ? "selected" : "";
  }
  Template.video_info.events = {
    'click': function(){
      Session.set('session_video', this._id);
    }
  }
  Template.video_info.creatorName = function () {
    var owner = Meteor.users.findOne(this.owner);
    if (owner._id === Meteor.userId())
      return "me";
    return displayName(owner);
  };
}
if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
  });
}

这是我的模型.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;
};
我想

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

if(Accounts.loginServicesConfigured()){
  var owner = Meteor.users.findOne(this.owner);
  if (owner._id === Meteor.userId())
    return "me";
  return displayName(owner);
}

目前,这似乎工作正常。我仍在深入研究如何订阅此用户服务。我在为此寻找解决方案时发现了几个非常有用的参考

  • https://github.com/oortcloud/unofficial-meteor-faq
  • http://psychopyko.com/cool-stuff/meteor-6-simple-tips/
  • https://groups.google.com/forum/#!topic/meteor-talk/QKXe7qfBfqg

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