【问题标题】:Meteor 0.8.0 - Failed to operate DOM in rendered callbackMeteor 0.8.0 - 无法在渲染回调中操作 DOM
【发布时间】:2014-05-12 12:36:21
【问题描述】:

0.8.0之前,以下代码可以完美运行。

<template name="carousel">
    <!--Here I used the carousel of Bootstrap-->
    <div id="myCarousel" class="carousel">
        <ol class="carousel-indicators">
        {{#each counter}}
            <li data-target="#myCarousel" data-slide-to="{{this}}"></li>
        {{/each}}
        </ol>
        <div class="carousel-inner">
            {{#each carousels}}
                <div class="item"><a href="{{link}}"><img src="{{src}}" ></a></div>
            {{/each}}
        </div>
        <a class="carousel-control left" href="#myCarousel" data-slide="prev">&lsaquo;</a>
        <a class="carousel-control right" href="#myCarousel" data-slide="next">&rsaquo;</a>
    </div>
</template>

Template.carousel.helpers({
    carousels: function() {
        return Carousels.find();
    },
    counter: function() {
        return _.range(0, Carousels.find().count());
    }
});

Template.carousel.rendered = function() {
    Meteor.defer(function() {
        $('#myCarousel .carousel-indicators li:first').addClass('active');
        $('#myCarousel .item:first').addClass('active');
    });
}

但更新到 0.8.0 后,添加 'active' 类不再起作用。 使用 Meteor.setTimeout 而不是 Meteor.defer,我终于发现它只有在延迟足够长(有时超过 150ms)时才有效。

Template.carousel.rendered = function() {
    Meteor.setTimeout(function() {
        $('#myCarousel .carousel-indicators li:first').addClass('active');
        $('#myCarousel .item:first').addClass('active');
    }, 150);
}

为什么会这样,有没有更好的解决办法?

[更新] 现在我使用一个简单的 isFirst 助手来实现它。我认为这是一个更好的解决方案。

{{#each carousels}}
    <div class="item {{isFirst _id}}"><a href="{{link}}"><img src="{{src}}" ></a></div>
{{/each}}

Template.carousel.isFirst = function(id) {
    return Carousels.find().fetch()[0]._id == id ? 'active' : '';
}

计数器,我只是让“计数器”从1开始,HTML如下:

<ol class="carousel-indicators">
    <li class="active" data-target="#myCarousel" data-slide-to="0"></li>
    {{#each counter}}
        <li data-target="#myCarousel" data-slide-to="{{this}}"></li>
    {{/each}}
</ol>

【问题讨论】:

  • 听起来像是竞争条件。但在哪里,用什么,我不知道。
  • 请查看我对一个非常相似的问题的回答here。您也可以遵循该模式。

标签: meteor


【解决方案1】:

Template.carousel.rendered 在Blaze(Meteor 的新渲染引擎)中只运行一次,但它曾经在 Spark(以前的版本)中运行多次。这种旧行为有效,因为它在您的 {{#each}} 块被渲染之前和之后运行。

这里的问题是 Template.carousel.rendered 在你的 {{#each}} 块被渲染之前运行,所以这些项目还不存在。

recommended pattern 是将您的 {{#each}} 的内容 放在一个单独的模板中,然后点击 that 模板的渲染事件。

顺便说一句,Meteor.defer 不再需要了。

【讨论】:

  • 谢谢。它可以工作,但渲染的回调将被多次调用。有时可能会导致一些新问题。
  • @Vanitas 如果没有节点已经拥有它,您可以通过添加“活动”或通过在 render() 之外设置“is_first_run”变量并仅在该变量为false,然后在运行时将其设置为 true...
  • 感谢您的帮助。我刚刚更新了问题以显示我的新解决方案,并且不再需要呈现的回调。再次感谢。
  • 那么你的问题解决了吗?如果是这样,则无需将答案放在问题中。只需将其中一个答案标记为已接受。 :) 干杯。
  • 是的。我把我的解决方案放在这里有两个原因:1.我最后不使用你的解决方案; 2.帮助有类似问题的人。
猜你喜欢
  • 2014-05-09
  • 2015-08-09
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 2014-05-11
相关资源
最近更新 更多