2016-01-13 56 views
0

我在Template.templatename.OnRendered中初始化datepickers和表單驗證。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我的模板,datepickers和表單驗證停止工作。沒有錯誤消息。

回答

1

這個問題被問了很多,但無可否認很難搜索。 This是一個關於渲染旋轉木馬項目的類似問題。

這裏發生的事情:

  1. 你的模板處理和onRendered被調用。
  2. 您的訂閱還沒有準備好,所以datepicker沒有呈現,但初始化代碼在(1)中運行,就好像它有。
  3. 最終呈現日期選擇器。

一個可能的答案是呈現在子模板中的日期選擇器。在子模板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> 

注意,你必須把你的日期選擇器初始化的東西在Tracker.afterFlush因爲它只的DOM實際呈現的下一個沖洗週期之後的。如果你沒有嵌入afterFlush,那麼datepicker的初始化將會被執行,但是不會有任何影響,因爲datepicker實際上還沒有在DOM中。

我已經使用這個選項無數次,當子模板,只是感覺強迫。