2014-04-01 4 views
3

0.8.0 이전에는 다음 코드가 완벽하게 작동합니다.Meteor 0.8.0 - 렌더링 된 콜백에서 DOM을 조작하지 못했습니다.

<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으로 업데이트 한 후 '활성'클래스를 추가하면 더 이상 작동하지 않습니다. Meteor.defer 대신 Meteor.setTimeout을 사용하여 마침내 지연이 충분히 길 때 (때로는 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> 
+0

경쟁 조건처럼 들립니다. 그러나 무엇을 어디에서, 나는 모르겠다. – Homer6

+0

매우 비슷한 질문 [내 대답] 체크 아웃하십시오 (http://stackoverflow.com/questions/22789821/meteor-0-8-blaze-how-to-update-rendered-changes-for-jquery-plugins) . 당신은 그 패턴을 따라갈 수 있습니다. –

답변

2

Template.carousel.rendered은 Blaze (유성의 새로운 렌더링에 한 번 실행 엔진), Spark (이전 버전)에서는 여러 번 실행되었습니다. 이 오래된 동작은 {{#each}} 블록이 렌더링되기 전후에 실행 되었기 때문에 작동했습니다.

여기서 문제는 {{#each}} 블록이 렌더링되기 전에 Template.carousel.rendered가 실행되므로 해당 항목이 아직 존재하지 않는다는 것입니다.

recommended pattern

해당 템플릿의 렌더링 이벤트에 내용에게 {{#each}}에 별도의 템플릿의을 넣어 활용할 수있다.

그런데 Meteor.defer는 더 이상 필요하지 않습니다.

+0

감사합니다. 그것은 작동하지만 렌더링 된 콜백은 여러 번 호출됩니다. 때때로 새로운 문제가 발생할 수 있습니다. –

+0

@Vanitas 이미 그 노드가 없다면 "active"를 추가하거나 rendered() 외부에서 "is_first_run"변수를 설정하고 해당 변수가 false 일 때만 실행 한 다음 true로 설정할 수 있습니다 달릴 때 ... – SuitedSloth

+0

도와 줘서 고마워. 방금 새 솔루션을 보여주기 위해 질문을 업데이트했으며 렌더링 된 콜백이 더 이상 필요하지 않습니다. 다시 한번 감사드립니다. –

관련 문제