【问题标题】:Meteor Templates helpers and access to collections' fields [duplicate]流星模板助手和访问集合的字段[重复]
【发布时间】:2016-02-12 19:54:31
【问题描述】:

我有两个收藏:

Group = {
  users: [Array_of_User]
}

User = {
  name: _string_
}

我正在列出组,并且我想在模板中知道用户是否在组中:

mytemplate.js

Template.mytemplate.helpers({
  groups: function(){
      return Groups.find();
  },
  currentUsername: 'test'
});

mytemplate.html

<template name="main">
  <ul>
    {{#each groups}}
    <li>
      {{#if [the group contains currentUsername] }}
      contains
      {{else}}
      doesn't contain
      {{/if}}
    </li>
    {{/each}}
  </ul>
</template>

问题是:我可以在 helpers 上而不是 [the group contains currentUsername] 上添加什么来使其工作?

另外,我并不是说这是这样做的方法。我愿意接受任何建议,即使这意味着我必须做出很多改变。

【问题讨论】:

  • @Kyll 我不这么认为,因为当你遇到这个问题时,你还必须知道在帮助者的部分放什么。所以,这不是一个只有 js 的问题,而是更多地与 Meteor 相关。顺便说一句,这在两个响应中得到了很好的解决。我刚刚相应地编辑了问题。
  • 我知道,但你对整个助手部分的理解非常好。唯一缺少的逻辑是在数组中实际找到元素,因此重复的建议。
  • 好吧,就我而言,我不知道我必须使用this 作为助手部分的数据范围。所以,它实际上真的很有帮助。但是要知道来这里的人会不会只知道js部分,我不知道。你可能是对的。

标签: javascript mongodb meteor spacebars meteor-helper


【解决方案1】:

您可以使用Underscore.js 函数_.findWhere(list, properties) 来检查该组是否包含用户名:

if (Meteor.isClient) {
    Template.main.helpers({
        groups: function() {
            return Groups.find();
        },
        currentUsername: 'Matthias',
        isInGroup: function(username) {
            return !!_.findWhere(this.users, {
                name: username
            });
        }
    });
}

<template name="main">
  <ul>
    {{#each groups}}
    <li>
      {{#if isInGroup currentUsername}}
        contains
      {{else}}
        doesn't contain
      {{/if}}
    </li>
    {{/each}}
  </ul>
</template>

if (Meteor.isServer) {
    Meteor.startup(function() {
        Groups.insert({
            users: [{
                name: "Matthias"
            }, {
                name: "Angie"
            }]
        });
    });
}

这是MeteorPad

【讨论】:

  • 为什么要添加外部库只是为了执行迭代,这可以通过 JS 轻松完成。
  • 你可能知道,Meteor 核心依赖于Underscore.js。因此,您可以在服务器和客户端上使用此库。但是,您不必这样做。我只是提出一种不同的方法,在我看来这比执行迭代更直观。
  • 我认为通常最好总是使用某种函数库来做这种事情,我个人使用 ramda,它比下划线好很多。但是下划线有效并且已预先打包......如果答案在帮助程序组(){}而不是组中使用更新的语法会更好:函数(){}等......
  • 像魅力一样工作(不过有一个小故障:应该是name: unsername)。实际上,在发布之前,我确实像这个答案一样使用了 JS .forEach 迭代。我的错误是没有在模板助手端使用this
  • Needz moar 下划线:_.contains(_.pluck(this.users, 'name'), username)_.pluck_.contains
【解决方案2】:

在您的每个块中,您的数据上下文成为正在迭代的当前组。因此,您可以编写一个引用当前数据上下文的辅助方法,如下所示:

userInGroup: function(username) {
  var userInGroup;
  this.forEach(function(groupUsername) {
    if (username == groupUsername) {
      userInGroup = true;
    }
  };
  return userInGroup;
}

userInGroup 模板助手中的'this' 引用当前组,只要您在组迭代中使用该助手。

然后您可以像这样使用帮助器:

<template name="main">
  <ul>
    {{#each groups}}
    <li>
      {{#if userInGroup currentUsername}}
      contains
      {{else}}
      doesn't contain
      {{/if}}
    </li>
    {{/each}}
  </ul>
</template>

【讨论】:

  • (我继续在这里)我完全同意,这是 SO 的限制,因为问题必须非常尖锐。版主急切地等待更多积分:p 下次我会发布我的代码! :) 顺便说一句,我很震惊有人投了你的反对票。我们可以讨论哪种解决方案更好,但你的肯定不是“坏”...
  • 是的,我不知道为什么有人会否决我的回答。 @matthias 的回答更简洁,他正确地告诉我下划线已经作为一个 dep 添加到 Meteor 中。但是,我的回答为偶然发现这个问题的随机观众提供了价值,因为我解释了基本逻辑。
猜你喜欢
  • 1970-01-01
  • 2014-06-09
  • 2017-03-14
  • 2015-08-07
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
  • 2015-07-12
相关资源
最近更新 更多