使用Meteor中的#each在动态数据中填充Bootstrap网格

时间:2013-09-17 08:21:05

标签: javascript twitter-bootstrap grid meteor

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

  1. 使用。
  2. 创建一行
  3. 在... element ...
  4. 中输出四个数据元素
  5. 用。
  6. 关闭'row div'
  7. 使用...
  8. 创建下一行
  9. 从步骤2中冲洗并重复。
  10. 使用{{#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>
    

    助手的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到结束当前行并开始下一行似乎不是由我期望的Boo​​tstrap(或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中的动态数据弹出网格的替代方法吗?

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:2)

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

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

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

一些伪代码:

{{#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}}

答案 2 :(得分:1)

不那么复杂的解决方案就是简单地使用Foundation Grid System的改编

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>