2014-06-05 4 views
0

Когда я пытаюсь использовать this.findAll в шаблоне, где селектор находится в подшаблоне, findAll ничего не возвращает.this.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); 
} 

Выход boxes.length 0. Любые идеи, как я мог бы получить элементы "коробки"?

ответ

0

Вот правильный ответ. Я добавил это к моему железо-маршрутизатор маршруту:

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

Найден ответ от https://stackoverflow.com/a/23576039/130237 в то время как я пытался решить другую проблему.

1

Согласно документации для findAll:

только элементы внутри шаблона и его подразделы шаблонов могут соответствовать частям селектора.

Так что это должно работать на подшаблоны. Я пробовал это с помощью фиксированного массива продуктов, и это сработало, что означает, что вы просто видите задержку между вызовом rendered и продуктами, которые вы получаете. Например, если вы:

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

Затем, если нажать на одну из коробок, вы должны увидеть правильный номер протоколирование в консоли. Короче говоря, я думаю, что тест может быть просто недействительным. Если вы используете железо-маршрутизатор, вы можете попробовать добавить waitOn для продуктов - это может гарантировать, что они будут доставлены до вынесенного вызова.

+0

Посмотрев на фактическую страницу, я наблюдаю, что есть какая-то задержка. Консоль.log уже показывала выход, прежде чем продукты появятся на странице. Я использую железо-маршрутизатор, и я использую waitOn для продуктов. Мне нужно запустить скрипт, когда все продукты были загружены. Любые другие идеи? – ian

+0

Это не так просто, потому что у метеор не действительно есть понятие «сделано», когда дело доходит до загрузки данных сбора. Что происходит при добавлении другого продукта? Если ответ состоит в том, чтобы снова запустить вашу функцию, я бы рекомендовал подумать о том, как использовать 'product.rendered' вместо' products.rendered'. Замечание - также стоит упомянуть, что вы всегда можете использовать '$ ('. Box')' в любой из функций, чтобы получить все поля на странице, хотя это может и не иметь смысла, если у вас есть несколько экземпляров 'products' шаблон. –

+0

Спасибо, Дэвид! Вы дали мне идею, как ее решить. Я отправлю ответ через некоторое время. – ian

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.products», я использовал «Template.product», чтобы обнаружить, если последний продукт визуализируется. Когда последний продукт отображается, запустите скрипт.

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

boxes.length теперь имеет правильную длину.

Благодаря Давиду за идею!

 Смежные вопросы

  • Нет связанных вопросов^_^