6

首先感谢您的帮助并原谅我的婴儿 Meteor 和 Bootstrap 技能。我遇到了与此处提出的问题类似的问题,该问题产生了一些建议但没有解决方案。我想使用#each 在 Meteor 模板中使用来自 MongoDB 的数据填充 BootStrap 网格。由于 BootStrap 网格有 12 列,我想每行显示 4 个“单元格”,我相信我需要 -

  1. 使用创建一行。
  2. 在 ...element... 中输出四个数据元素
  3. 用 关闭“行 div”。
  4. 使用...创建下一行
  5. 冲洗并从步骤 2 开始重复。

使用从数组/集合返回数据的 {{#each...}} 块执行第 2 步。

我的流星模板看起来像这样(我正在从优秀的“发现流星”一书中扩展一个例子) -

<template name="postsList"> 
<div class="posts">
   <div class='row-fluid' style="margin-left:1%">
      {{breakInit}}
      {{#each posts}}
         <div class="span3">
           {{> postItem}}
         </div>
         {{breakNow}}
      {{/each}}
   </div>
</div> 
</template>

Helpers 的 JavaScript 看起来像这样 -

Template.postsList.breakInit = function() {
Template.postsList.docCount = 0 ;
};

Template.postsList.breakNow = function() {
count=Template.postsList.docCount + 1 ;
result="";
if ( count == 4 ) {
    count = 0 ;
    Template.postsList.docCount = count ;
    result="</div><div class=row>" ;
};
Template.postsList.docCount = count ;
return new Handlebars.SafeString(result);
};

这一切似乎都有效,至少在计算#each 输出的元素、返回</div><div class=row>以开始新行并重置计数器方面......但是......返回的 HTML 结束当前行并开始下一个Bootstrap(或 Meteor 或我的浏览器)似乎没有像我期望的那样处理它。它似乎被重新排序为<div class=row></div>. 请参阅 FireFox 中 Inspector 的此屏幕截图(代码输出 6 个元素,第一行 4 个,第二行 2 个)-

<div id="main" class="row-fluid">
  <div class="posts">
    <div class="row">
      <div class="span3"> … </div>
      <div class="span3"> … </div>
      <div class="span3"> … </div>
      <div class="span3"> … </div>
      <div class="row"> … </div>  <-- The problem...
      <div class="span3"> … </div>
      <div class="span3"> … </div>
    </div>
  </div>
</div>

注意<div class=row>...</div>跨度中间的?看起来不对,它应该关闭前一个“行”DIV 并开始下一个。任何人都可以建议修复我的代码或使用 Meteor 中的动态数据填充网格的替代方法吗?

4

3 回答 3

9

您可以在呈现数据之前对数据进行分组:

Template.projectList.helpers({
    projects: function () {
        all = Projects.find({}).fetch();
        chunks = [];
        size = 4;
        while (all.length > size) {
            chunks.push({ row: all.slice(0, size)});
            all = all.slice(size);
        }
        chunks.push({row: all});
        return chunks;
    }
});

<template name="projectList">
  {{#each projects}}
    {{> projectRow }}
  {{/each}}
</template>

<template name='projectRow'>
  <div class='row span12'>
    {{#each row }}
      {{> projectItem}}
    {{/each}}
  </div>
</template>

<template name="projectItem">
  <div class="span4">
    <h3><a href="{{projectPagePath this}}"> {{title}} </a></h3>
    <p> {{subtitle}} </p>
    <p> {{description}} </p>
    <p><img src="{{image}}"/></p>
    <p> {{openPositions}} </p>
  </div>
</template>
于 2013-09-17T19:33:45.863 回答
2

问题在于尝试添加无效的 HTML ( </div><div class=row>)。即使作为 DocumentFragment,它也是无效的(通常,Document 和 DocumentFragment 之间的区别在于 Document 只能有一个文档元素(例如根节点<html>),而 DocumentFragment 可以有多个文档元素)。

因此,当 Spark 尝试处理您的字符串并将其填充到 DOM 中时,它会自动更正。它也超出了 Spark 的控制范围,浏览器 DOM 可以做到这一点。

你需要做的是做一个 each 嵌套在另一个 each 中。第一个将遍历行,第二个遍历该行的列。

一些伪代码:

{{#each rows}}
    <div class="row-fluid">
        {{#each posts row}}
            <div class="span3">
                {{> postItem}}
            </div>
        {{/each}}
    </div>
{{/each}}

Template.postsList.rows = function () {
    // 1. Get cursor of posts (cursor = posts.find({...});
    // 2. Get count from cursor (count = cursor.count());
    // 3. Divide count by desired columns per row, then Math.ceil it (I think!)
    // 4. Return an array of objects each containing a "row" key, with some various values (current row probably, count, etc)
};

Template.postsList.posts = function (row) {
    // Return a cursor of posts that is offset and limited (see meteor docs) based on values found in the row object
};

希望这足以让你继续前进。

编辑:在步骤 3 中(除以每行所需的列数),您可能会将此数字来自模板,因此您不会在代码和模板之间混合这些细节。例如:{{#each rows 4}}

于 2013-09-17T12:30:11.640 回答
1

不太复杂的解决方案是简单地使用基础网格系统的改编

https://github.com/JohnnyTheTank/bootstrap-block-grid

它遵循一种更好的方法,您只需定义一次列数,所有元素都将遵循该规则和动态布局。

<div class="block-grid-xs-2 block-grid-sm-3 block-grid-md-4">
    <div>
        Content 1
    </div>
    <div>
        Content 2
    </div>
    <div>
        Content 3
    </div>
    <div>
        Content 4
    </div>
    <div>
        Content 5
    </div>
    <div>
        Content 6
    </div>
</div>
于 2016-08-30T22:02:26.243 回答