【问题标题】:How to create a bootstrap "row" dynamically using knockout foreach binding in razor如何在剃须刀中使用淘汰赛 foreach 绑定动态创建引导“行”
【发布时间】:2017-10-27 04:04:11
【问题描述】:

这是我的 cshtml 文件中的代码 sn-p,我在其中使用敲除循环来显示内容:

<div data-bind="visible: results().length > 0, foreach: results">    
    <div class="row">
    <!-- ko if: ImageTileSize == "2" -->    
        <div class="col-md-6">
    <!-- /ko -->
    <!-- ko if: ImageTileSize == "1" -->    
        <div class="col-md-3">
    <!-- /ko -->
            <a data-bind="attr: { href: Link }" class="powering-article">
                <div class="powering-listimg">
                <img data-bind="attr: { src: ImageUrl }" alt="" class="img-responsive">
                </div>
                <p><span data-bind="    text: PublishedDate.format('DD MMM YYYY')"></span> | <strong><span data-bind="    text: Category"></span></strong></p>
                <h2 data-bind="text: Title"></h2>
            </a>
        </div>
    </div>
</div>

注意:ImageTIleSize 将始终为 1 或 2。

我喜欢在 for 循环中应用计数器,因此如果 ImageTileSize 大于 4,则在循环内创建另一个行 div 标签,内容与上述相同。

我不完全确定如何将淘汰赛值传递给剃须刀:

@int count = 0;
<div data-bind...
    @if(..

    }
    ...
    @count = count + ImageTileSize; //doesn't work, can't grab the ImageTileSize value
</div>

更新:

这是 bootstrap 当前处理每 12 列之后的行的方式:

“第 1 条”应该在“第 3 条”下开始,但它在“第 2 条”下发现自己有足够的空间。虽然,如果我要添加像“第 4 条”这样的大图像,那么它的位置是正确的。

【问题讨论】:

    标签: asp.net-mvc razor knockout.js


    【解决方案1】:

    这里有几点需要注意:

    • Razor 代码在服务器端运行。 ImageTileSizeresults obserableArray 中每个对象的属性。您不能将它与您的 c# count 变量一起使用。

    • 您的Containerless control flow syntax 无效。它们的行为类似于 HTML 元素。在您的情况下,div 标签没有结束标签。

    我假设您想为引导网格系统的每个“12 列”获取一个新的row。你可以这样做:

    <div class="row" data-bind="visible: results().length > 0, foreach: results">
        <div data-bind="attr: { class: ImageTileSize == '1' ? 'col-md-3' : 'col-md-6' }">
            <a data-bind="attr: { href: Link }" class="powering-article">
                <div class="powering-listimg">
                <img data-bind="attr: { src: ImageUrl }" alt="" class="img-responsive">
                </div>
                <p><span data-bind="    text: PublishedDate.format('DD MMM YYYY')"></span> | <strong><span data-bind="    text: Category"></span></strong></p>
                <h2 data-bind="text: Title"></h2>
            </a>
       </div>
    </div>
    

    Here's a fiddle 用于测试。我已将类从col-md-* 更改为col-xs-*,因为结果窗口很小并且所有col-md- 都在新行中呈现。

    请注意,这不会在每“12 列”之后生成一个新的&lt;div class="row"&gt;。但是引导程序会自动处理它。每当它无法容纳下一个col-md-3时,它会默认移动到下一行。


    更新:

    如果您仍想为每个“12 列”创建一个新的row,那么您可以创建一个名为groupedResultscomputed 属性。这将是一个数组数组。每个内部数组将包含每个rowresults。这里的想法是遍历 results 并将它们分组以适应引导程序 row

    // this array looks: [[result1,result2,result3], [result4,result5]] based on tile width of each result
    self.groupedResults = ko.computed(function() {
        var rows = [];
        var count = 0; // image tile count for current row
    
        self.results().forEach(function(item, i) {
          // initialize new inner array when count = 0 
          // or when the total tile count > 4
          if (count == 0 || (count + parseInt(item.ImageTileSize)) > 4) {
            rows[rows.length] = [item];
            count = parseInt(item.ImageTileSize);
          } else {
            rows[rows.length - 1].push(item);
            count += parseInt(item.ImageTileSize);
          }
        });
    
        return rows;
    });
    

    然后在你的 HTML 中:

    <div data-bind="visible: groupedResults().length > 0, foreach: groupedResults">
      <div class="row" data-bind="foreach: $data">
        <div style="text-align: center" data-bind="attr: { class: ImageTileSize == '1' ? 'col-md-3' : 'col-md-6' }">
            <a data-bind="attr: { href: Link }" class="powering-article">
                <div class="powering-listimg">
                <img data-bind="attr: { src: ImageUrl }" alt="" class="img-responsive">
                </div>
                <p><span data-bind="    text: PublishedDate.format('DD MMM YYYY')"></span> | <strong><span data-bind="    text: Category"></span></strong></p>
                <h2 data-bind="text: Title"></h2>
            </a>
        </div>
      </div>
    </div>
    

    $data 这里是上下文中的内部数组。 You can read about binding context here.

    Here's a fiddle for this computed implementation

    【讨论】:

    • 嗨@adiga,这真的很有帮助,感谢您清理代码。我已经编辑了我的帖子,以向您展示它在超过 12 列之后的样子。我认为引导程序会处理它,但不确定为什么它不会,因此我打算添加
      方法。知道如何解决这个问题吗?
    • 老实说,我对 Knockout 库并不熟悉,我们的供应商使用了它,但它们不再为我们工作了。这是 jfiddle 链接(jsfiddle.net/bx9ma9zf/1),能告诉我在哪里可以插入您的代码吗?感谢您的所有帮助!
    • 这很简单。 Knockout 需要一个带有或不带有observables 的javascript 对象。创建对象的方法有很多。我所做的是使用构造函数。在您的情况下,它是这样创建的var vm = {}。所以你必须向它添加一个名为groupedResults 的属性。这是updated fiddle
    • 哇,太完美了,基本上解决了我的问题。还有一件事,既然你是专家,我喜欢返回数组中除第一项之外的所有结果,我该怎么做?我曾经在 for 循环之后使用 但我想这不再起作用了..
    • @Vipresh 在forEach 中,您可以像这样跳过第零个indexself.results().forEach(function(item, i) { if(i == 0) return; &lt;rest of the code&gt;..... }
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签