2016-01-13 49 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中。

我已经使用这个选项无数次,当子模板,只是感觉强迫。