【问题标题】:Meteor : best practice for modifying Mongo query result before template takes it?Meteor:在模板采用之前修改 Mongo 查询结果的最佳实践?
【发布时间】:2015-05-03 00:00:33
【问题描述】:

学习 Meteor,我仍然陷入概念泥潭。

我有一个集合,其中每个项目都有一个名为“props”的数组,其中包含零个或多个属性名称:loudmouth、fixer、networker、outcast 等。

我还有一组属性对象,每个对象都与一个字形图标相关联。

现在,我的模板将数据项显示为包含属性标识符的

  • 行的无序列表。我想用相应的图标 HTML 替换属性标识符
    {name: "loudmouth", icon: "bullhorn", other: "rtgb"}
    {name: "fixer", icon: "wrench", other: "iun"}
    {name: "networker", icon: "link", other: "retf"}
    {name: "outcast", icon: "ban-circle", other: "vcfdds"}
    

    所以这个...

    <li>AAA loudmouth fixer outcast</li>
    <li>BBB fixer networker</li>
    

    ...应该变成这个...

    <li>AAA <span class="glyphicon glyphicon-bullhorn" aria-hidden="true"></span> <span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <span class="glyphicon glyphicon-ban-circle" aria-hidden="true"></span></li>
    <li>BBB <span class="glyphicon glyphicon-wrench" aria-hidden="true"></span> <span class="glyphicon glyphicon-link" aria-hidden="true"></span></li>
    

    这不是 SQL 连接;我正在为每个返回的结果项添加属性。最好的方法是什么?

    我尝试了几种方法,但它们真的很乱。

    1) 第一个是客户端中粗略的内/外循环作业。对于外部的每个数据项,我会附加 标记,这些标记是从内部循环的字符串中连接起来的。这似乎给了我某种竞争条件,带有虚假的“未定义”。 (我还不清楚它的同步性规则)。我应该将属性集合预取到名称/值映射对象中吗?另外,奇怪的是,我的 HTML 显示的是 标签的文本而不是图标?!?!嗯?

    2) 然后我尝试使用 Meteor.method 和 Meteor.call 在服务器端执行此操作。我无法同步取回数据,也不真正理解如何异步填充模板(来自回调)。您是否在 Template.mine.created() 期间填充了一个数组,然后从 Template.mine.helper 返回该数组? Meteor.method / Meteor.call 组合应该用于更改后端数据,NOT 用于检索后端数据,我对吗?

    有没有人知道关于这种事情的好教程?你会怎么做?

    我希望这不会因为“基于意见”而被拒绝,我相信所有有效的替代方案都会帮助其他有相关问题需要解决的人。

  • 【问题讨论】:

      标签: javascript mongodb templates meteor conceptual


      【解决方案1】:

      您可以使用参数化模板来做到这一点:

      <template name="glyph">
       <span class="glyphicon glyphicon-{{icon this}}" aria-hidden="true"></span>
      </template>
      

      添加一个辅助函数,如:

      Template.glyph.helpers({
          icon: function(name) {
                  return <Iconcollection>.findOne({name:name}).icon
          }   
      }); 
      

      然后你可以在你的模板中做这样的事情:

      {{> glyph 'fixer'}}
      

      或者,如果参数来自您的迭代器对象

      {{> glyph name}}
      

      (假设您的对象具有.name 属性)

      无论如何,我建议您重新阅读并尝试 Meteor 中的助手和反应性。由于您已经在客户端中拥有该集合,因此您通常只需使用辅助函数即可解决此类问题。 Meteor 会随着集合的更新(重新)计算,因此您永远不必担心它。

      【讨论】:

      • 这真的很有趣。但是,为什么是 {{icon this}} 而不是 {{icon}} ?所以,事实上,我必须这样做:
      • {{fullName}} {{#each prop}} {{> glyph name}} {{/each}}
      • 。是吗?
    • 是的,您可以直接使用{{icon}},因为模板上下文(“数据”)会延续到嵌入式模板中,我忘记了这一点。是的,如果 prop.name 存在,它应该可以正常工作。
    • 【解决方案2】:

      检查我的理解: 1 个用户拥有 1 个属性。 1 个属性有 1 个name、1 个icon、1 个other

      如果是这种情况,请在门口检查您的 3NF,并将其嵌入到用户文档中。因此,您的架构可能如下所示:

      {userId: 'asldkfjz', 
       userName: 'Jonny', 
       properties: {
         name: "loudmouth", 
         icon: "bullhorn", 
         other: "rtgb"
       }
      }
      

      使用 MongoDB,您始终需要权衡空间成本和访问成本。存储 1 个外键 + 额外订阅可能(最肯定)比 3 个字符串更昂贵,对吧?

      接下来,我将如何设置您的模板:

      {{#each user}}
          {{>formatRow icon=properties.icon name=properties.name other=properties.other}}
      {{/each}}
      
      <template name="formatRow">
        <div class="blah">
          <li>{{name}} 
              <span class="glyphicon {{icon}}" aria-hidden="true"></span> 
          </li>
        </div>
      </template>
      

      我创建了一个包含 3 个变量的模板:iconnameother。然后,在我的主模板中,我传入这些变量。我将这两个步骤分开是因为稍后您可能会遇到比lispan 更多的垃圾,或者您需要在另一个模板中执行此操作,这使它们保持模块化。

      剩下要做的就是设置一个可以访问集合的模板助手:

      Template.foo.helpers({
        user: function () {
          return users.find();
        }
      });
      

      了解更多信息:

      http://docs.meteor.com/#/full/template_helpers https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md

      【讨论】:

      • 很抱歉,一个用户作为一组属性:
      • AAA 大嘴固定器弃儿
    • 您在收藏中存储一个 HTML 字符串?
    • 完全有可能,但不会影响我试图解决的概念问题。
    • 顺便说一句,我非常感谢您回答的细节,但真正的问题是在从后端到前端的数据流中的某个点用图标名称替换零个或多个属性名称的正确方法-结束。
    • 猜你喜欢
      相关资源
      最近更新 更多
      热门标签