TypeError: Cannot read property 'date' of undefined when using tsega:bootstrap3-datetimepicker in Meteor app
TypeError: Cannot read property 'date' of undefined when using tsega:bootstrap3-datetimepicker in Meteor app
我已经设置了一个使用 tsega:bootstrap3-datetimepicker 作为日期的流星应用程序。
我在detail.js中有以下内容:
Template.detail.helpers({
editbuttonstate: function () {
return (Session.get('editing')) ? 'glyphicon-ok' : 'glyphicon-pencil';
},
formattedStartDate: function () {
return moment(this.startDate).format('DD/MM/YYYY HH:mm');
},
formattedEndDate: function () {
return moment(this.endDate).format('DD/MM/YYYY HH:mm');
}
});
Template.detail.events({
'click .toggle-edit': function (e) {
e.preventDefault();
var editflag = Session.equals('editing', true);
if (!editflag) {
initDateTimePickers();
} else if (Meteor.userId()) {
var updatedEvent = {};
updatedEvent.startDate = $('#input-start-date').data('DateTimePicker').date().toDate();
updatedEvent.endDate = $('#input-end-date').data('DateTimePicker').date().toDate();
updatedEvent.owner = Meteor.userId();
Events.upsert({
_id: this._id
}, {
$set: updatedEvent
});
}
if (!editflag && !Meteor.userId()) {
return;
}
Session.set('editing', (!editflag));
}
});
Template.detail.rendered = function() {
initDateTimePickers();
};
var initDateTimePickers = function() {
var now = new Date();
$('.datetimepicker').datetimepicker({
locale: 'en_gb',
format: 'DD/MM/YYYY HH:mm',
defaultDate: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 12, 0, 0)
});
$('.set-due-date').focus(function () {
$('.datetimepicker').data("DateTimePicker").show();
});
$("#input-start-date").on("dp.change", function (e) {
$('#input-end-date').data("DateTimePicker").minDate(e.date);
});
$("#input-end-date").on("dp.change", function (e) {
$('#input-start-date').data("DateTimePicker").maxDate(e.date);
});
};
...以及以下 detail.html:
<template name="detail">
<div class="page page-detail">
<div class="container">
{{#if editing}}
<div class="input-group datetimepicker" id="input-start-date">
<span class="input-group-addon" id="addon-quote">Start</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedStartDate}}" />
</div>
<div class="input-group datetimepicker" id="input-end-date">
<span class="input-group-addon" id="addon-quote">End</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedEndDate}}" />
</div>
{{else}}
<h4 class="title">Start: {{formattedStartDate}}</h4>
<h4 class="title">End: {{formattedEndDate}}</h4>
{{/if}}
</div>
<div class="container">
<div class="btn btn-danger toggle-edit pull-right">
<span class="glyphicon {{editbuttonstate}}"></span>
</div>
</div>
</div>
</template>
首次呈现模板时,日期时间选择器工作正常,但是当单击保存按钮然后单击编辑按钮时,日期时间选择器不再起作用。
保存后,它们会产生如下错误:
TypeError: 无法读取未定义的 属性 'date'
有人知道可能遗漏了什么吗?
看起来每次单击 edit/save 按钮时,都会为 display/edit 模式生成新的 HTML 元素,包括构成日期时间选择器的元素。因此,每次切换编辑模式时都必须重新初始化日期时间选择器。
实现此目的的一种方法是将编辑视图的核心分离到一个单独的模板中,如下所示。
detail.js
Template.detail.helpers({
editbuttonstate: function () {
return (Session.get('editing')) ? 'glyphicon-ok' : 'glyphicon-pencil';
},
editing: function () {
return (Session.equals('editing', true));
},
formattedStartDate: function () {
return moment(this.startDate).format('DD/MM/YYYY HH:mm');
},
formattedEndDate: function () {
return moment(this.endDate).format('DD/MM/YYYY HH:mm');
}
});
Template.edit_detail.helpers({
gameActive: function () {
return this.type === "game" ? "active" : "";
},
tournamentActive: function () {
return this.type === "tournament" ? "active" : "";
},
trainingActive: function () {
return this.type === "training" ? "active" : "";
},
campActive: function () {
return this.type === "camp" ? "active" : "";
},
formattedStartDate: function () {
return moment(this.startDate).format('DD/MM/YYYY HH:mm');
},
formattedEndDate: function () {
return moment(this.endDate).format('DD/MM/YYYY HH:mm');
}
});
Template.detail.events({
'click .toggle-edit': function (e) {
e.preventDefault();
var editflag = Session.equals('editing', true);
if (editflag && Meteor.userId()) {
var updatedEvent = {};
updatedEvent.startDate = $('#input-start-date').data("DateTimePicker").date().toDate();
updatedEvent.endDate = $('#input-end-date').data("DateTimePicker").date().toDate();
updatedEvent.owner = Meteor.userId();
Events.upsert({
_id: this._id
}, {
$set: updatedEvent
});
}
if (!editflag && !Meteor.userId()) {
return;
}
Session.set('editing', (!editflag));
}
});
Template.edit_detail.rendered = function() {
initDateTimePickers();
};
var initDateTimePickers = function() {
if (Session.equals('editing', true)) {
var now = new Date();
$('.datetimepicker').datetimepicker({
locale: 'en_gb',
format: 'DD/MM/YYYY HH:mm',
defaultDate: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 12, 0, 0)
});
$('#input-end-date').data("DateTimePicker").minDate(now);
$('#input-start-date').data("DateTimePicker").maxDate(now);
$("#input-start-date").on("dp.change", function (e) {
$('#input-end-date').data("DateTimePicker").minDate(e.date);
});
$("#input-end-date").on("dp.change", function (e) {
$('#input-start-date').data("DateTimePicker").maxDate(e.date);
});
}
};
detail.html
<template name="detail">
<div class="page page-detail">
<div class="container">
{{#if editing}}
{{> edit_detail}}
{{else}}
<h4 class="title">Start: {{formattedStartDate}}</h4>
<h4 class="title">End: {{formattedEndDate}}</h4>
{{/if}}
</div>
<div class="container">
<div class="btn btn-danger toggle-edit pull-right">
<span class="glyphicon {{editbuttonstate}}"></span>
</div>
</div>
</div>
</template>
<template name="edit_detail">
<div class="input-group datetimepicker" id="input-start-date">
<span class="input-group-addon" id="addon-quote">Start</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedStartDate}}" />
</div>
<div class="input-group datetimepicker" id="input-end-date">
<span class="input-group-addon" id="addon-quote">End</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedEndDate}}" />
</div>
</template>
在呈现新模板时将日期时间选择器的初始化代码移至 运行 可解决问题。
我已经设置了一个使用 tsega:bootstrap3-datetimepicker 作为日期的流星应用程序。
我在detail.js中有以下内容:
Template.detail.helpers({
editbuttonstate: function () {
return (Session.get('editing')) ? 'glyphicon-ok' : 'glyphicon-pencil';
},
formattedStartDate: function () {
return moment(this.startDate).format('DD/MM/YYYY HH:mm');
},
formattedEndDate: function () {
return moment(this.endDate).format('DD/MM/YYYY HH:mm');
}
});
Template.detail.events({
'click .toggle-edit': function (e) {
e.preventDefault();
var editflag = Session.equals('editing', true);
if (!editflag) {
initDateTimePickers();
} else if (Meteor.userId()) {
var updatedEvent = {};
updatedEvent.startDate = $('#input-start-date').data('DateTimePicker').date().toDate();
updatedEvent.endDate = $('#input-end-date').data('DateTimePicker').date().toDate();
updatedEvent.owner = Meteor.userId();
Events.upsert({
_id: this._id
}, {
$set: updatedEvent
});
}
if (!editflag && !Meteor.userId()) {
return;
}
Session.set('editing', (!editflag));
}
});
Template.detail.rendered = function() {
initDateTimePickers();
};
var initDateTimePickers = function() {
var now = new Date();
$('.datetimepicker').datetimepicker({
locale: 'en_gb',
format: 'DD/MM/YYYY HH:mm',
defaultDate: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 12, 0, 0)
});
$('.set-due-date').focus(function () {
$('.datetimepicker').data("DateTimePicker").show();
});
$("#input-start-date").on("dp.change", function (e) {
$('#input-end-date').data("DateTimePicker").minDate(e.date);
});
$("#input-end-date").on("dp.change", function (e) {
$('#input-start-date').data("DateTimePicker").maxDate(e.date);
});
};
...以及以下 detail.html:
<template name="detail">
<div class="page page-detail">
<div class="container">
{{#if editing}}
<div class="input-group datetimepicker" id="input-start-date">
<span class="input-group-addon" id="addon-quote">Start</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedStartDate}}" />
</div>
<div class="input-group datetimepicker" id="input-end-date">
<span class="input-group-addon" id="addon-quote">End</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedEndDate}}" />
</div>
{{else}}
<h4 class="title">Start: {{formattedStartDate}}</h4>
<h4 class="title">End: {{formattedEndDate}}</h4>
{{/if}}
</div>
<div class="container">
<div class="btn btn-danger toggle-edit pull-right">
<span class="glyphicon {{editbuttonstate}}"></span>
</div>
</div>
</div>
</template>
首次呈现模板时,日期时间选择器工作正常,但是当单击保存按钮然后单击编辑按钮时,日期时间选择器不再起作用。
保存后,它们会产生如下错误:
TypeError: 无法读取未定义的 属性 'date'
有人知道可能遗漏了什么吗?
看起来每次单击 edit/save 按钮时,都会为 display/edit 模式生成新的 HTML 元素,包括构成日期时间选择器的元素。因此,每次切换编辑模式时都必须重新初始化日期时间选择器。
实现此目的的一种方法是将编辑视图的核心分离到一个单独的模板中,如下所示。
detail.js
Template.detail.helpers({
editbuttonstate: function () {
return (Session.get('editing')) ? 'glyphicon-ok' : 'glyphicon-pencil';
},
editing: function () {
return (Session.equals('editing', true));
},
formattedStartDate: function () {
return moment(this.startDate).format('DD/MM/YYYY HH:mm');
},
formattedEndDate: function () {
return moment(this.endDate).format('DD/MM/YYYY HH:mm');
}
});
Template.edit_detail.helpers({
gameActive: function () {
return this.type === "game" ? "active" : "";
},
tournamentActive: function () {
return this.type === "tournament" ? "active" : "";
},
trainingActive: function () {
return this.type === "training" ? "active" : "";
},
campActive: function () {
return this.type === "camp" ? "active" : "";
},
formattedStartDate: function () {
return moment(this.startDate).format('DD/MM/YYYY HH:mm');
},
formattedEndDate: function () {
return moment(this.endDate).format('DD/MM/YYYY HH:mm');
}
});
Template.detail.events({
'click .toggle-edit': function (e) {
e.preventDefault();
var editflag = Session.equals('editing', true);
if (editflag && Meteor.userId()) {
var updatedEvent = {};
updatedEvent.startDate = $('#input-start-date').data("DateTimePicker").date().toDate();
updatedEvent.endDate = $('#input-end-date').data("DateTimePicker").date().toDate();
updatedEvent.owner = Meteor.userId();
Events.upsert({
_id: this._id
}, {
$set: updatedEvent
});
}
if (!editflag && !Meteor.userId()) {
return;
}
Session.set('editing', (!editflag));
}
});
Template.edit_detail.rendered = function() {
initDateTimePickers();
};
var initDateTimePickers = function() {
if (Session.equals('editing', true)) {
var now = new Date();
$('.datetimepicker').datetimepicker({
locale: 'en_gb',
format: 'DD/MM/YYYY HH:mm',
defaultDate: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 12, 0, 0)
});
$('#input-end-date').data("DateTimePicker").minDate(now);
$('#input-start-date').data("DateTimePicker").maxDate(now);
$("#input-start-date").on("dp.change", function (e) {
$('#input-end-date').data("DateTimePicker").minDate(e.date);
});
$("#input-end-date").on("dp.change", function (e) {
$('#input-start-date').data("DateTimePicker").maxDate(e.date);
});
}
};
detail.html
<template name="detail">
<div class="page page-detail">
<div class="container">
{{#if editing}}
{{> edit_detail}}
{{else}}
<h4 class="title">Start: {{formattedStartDate}}</h4>
<h4 class="title">End: {{formattedEndDate}}</h4>
{{/if}}
</div>
<div class="container">
<div class="btn btn-danger toggle-edit pull-right">
<span class="glyphicon {{editbuttonstate}}"></span>
</div>
</div>
</div>
</template>
<template name="edit_detail">
<div class="input-group datetimepicker" id="input-start-date">
<span class="input-group-addon" id="addon-quote">Start</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedStartDate}}" />
</div>
<div class="input-group datetimepicker" id="input-end-date">
<span class="input-group-addon" id="addon-quote">End</span>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
<input class="set-due-date form-control" type="text" value="{{formattedEndDate}}" />
</div>
</template>
在呈现新模板时将日期时间选择器的初始化代码移至 运行 可解决问题。