0

当我尝试在选择器位于子模板中的模板上使用 this.findAll 时,findAll 什么也不返回。

这是HTML:

<template name="products">
    {{#each productList}}
        {{> product }}
    {{/each}}
</template>
<template name="product">
    <div class="box">{{name}}</div>
</template>

这是JS:

Template.products.helpers({
    productList: function() {
        var all = Products.find({}).fetch();
        return all;
    }
});
Template.products.rendered = function(){
    var boxes = this.findAll('.box');
    console.log(boxes.length);
}

box.length 的输出为 0。有什么想法可以得到“box”元素吗?

4

3 回答 3

1

根据findAll的文档:

只有模板及其子模板内的元素可以匹配选择器的部分内容。

所以它应该适用于子模板。我用一组固定的产品尝试了这个,它起作用了,这意味着你只是看到调用rendered和获取产品之间的延迟。例如,如果您这样做:

Template.products.events({
  'click .box': function (e, t) {
    var boxes = t.findAll('.box');
    console.log(boxes.length);
  }
});

然后,如果您单击其中一个框,您应该会看到记录到控制台的正确数字。简而言之,我认为测试可能只是无效的。如果您使用的是 Iron-router,您可以尝试为产品添加 waitOn - 这可以确保它们在渲染调用之前到达。

于 2014-06-05T04:34:59.097 回答
0

这是我在加载所有产品后运行脚本所做的。

我在所有产品中添加了 last_product 属性。

Template.products.helpers({
    productList: function() {
        var all = Products.find({}).fetch();
        var total = all.length;
        var ctr = 0;
        all.forEach(function(doc){
            doc.last_product = false;

            ctr++;
            if(ctr == total)
            {
                doc.last_product = true;
            }
            return doc;
        });
        return all;
    }
});

然后,我使用“Template.product”而不是“Template.products”来检测是否呈现了最后一个产品。呈现最后一个产品时,运行脚本。

Template.product.rendered = function(){
    if(this.data.last_product){
        var boxes = $('.pbox');
        console.log(boxes.length);
    }
}

box.length 现在具有正确的长度。

感谢大卫的想法!

于 2014-06-05T06:12:12.510 回答
0

这是正确的答案。我已将此添加到我的 Iron-router 路由中:

action : function () {
    if (this.ready()) {
        this.render();
    }
}

当我试图解决一个不同的问题时,从https://stackoverflow.com/a/23576039/130237找到了答案。

于 2014-06-06T03:56:03.767 回答