2016-01-13 2 views
0

Я инициализирую datepickers и проверяю форму в Template.templatename.OnRendered.Template.subscriptionsReady отключает onRendered функциональность

$('#dateAccepted').datepicker({ 
    endDate: new Date(), 
    todayBtn: true, 
    todayHighlight: true, 
    autoclose: true 
}); 

Я делаю подписки, сбор запросов и т.д. в Template.templatename.onCreated.

Template.insertContract.onCreated(function() { 
var self = this; 
self.autorun(function() { 
    self.subscribe('getContracts'); 
    self.subscribe('getSuppliers' ,function(){ 
     var suppliers = Supplier.find({}).fetch(); 
     var sOptions = createOptions('supplier','supplierName',suppliers, true); 
     Session.set('supplierOptions', sOptions); 
    }); 
    self.subscribe('getItems'); 
}); 

});

Если я помещаю Template.subscriptionsReady в мой шаблон, даты и вычитания формы перестают работать. Нет сообщений об ошибках.

ответ

1

Этот вопрос задают много, но, по общему признанию, его трудно найти. This - это аналогичный вопрос об рендеринге карусели.

Вот что происходит:

  1. Ваш шаблон делает и onRendered вызывается.
  2. Ваша подписка еще не готова, поэтому datepicker не отображается, но код инициализации работает в (1), как если бы он был.
  3. В конце концов отображается датапикер.

Один из возможных вариантов ответа заключается в том, чтобы сделать datepicker в подшаблоне. В подкатегории onRendered вы можете запустить код инициализации, так как вы можете быть уверены, что он находится в DOM. См. Ответ на вышеупомянутый вопрос для примера.

0

То, что описано Дэвидом, является подходом к подрамнику, и в нескольких случаях это хороший вариант (я делал это много раз сам).

Но иногда просто не нужно создавать суб-шаблон, особенно если он будет содержать все (или большую часть) исходного шаблона. В этой ситуации вы можете просто переместить свою подписную логику на обратный вызов onRendered и использовать ReactiveVar для запуска обработки шаблона.

Вот пример:

Template.showStuff.onRendered(function() { 
    this.isReady = new ReactiveVar(false); 

    this.subscribe('mySubscription',() => { 
    this.isReady.set(true); 

    Tracker.afterFlush(() => { 
     this.$('#dateAccepted').datepicker({ 
     endDate: new Date(), 
     todayBtn: true, 
     todayHighlight: true, 
     autoclose: true 
     }); 
    }); 
    }); 
}); 

Затем определите помощника для использования в шаблоне.

Template.showStuff.helpers({ 
    isReady: function() { 
    return Template.instance().isReady.get(); 
    }; 
}); 

И оберните материал в свой шаблон, который зависит от подписки, используя вышеупомянутый помощник.

<template name="showStuff"> 
    {{#if isReady}} 
    ...datepicker and form stuff 
    {{/if}} 
</template> 

Обратите внимание, вы должны положить Datepicker инициализации вещи в Tracker.afterFlush, потому что это только после следующего цикла промывки, что DOM фактически оказанной. Если вы не вставляете в afterFlush, тогда инициализация datepicker будет выполнена, но не повлияет, потому что datepicker еще не находится в DOM.

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