我有一个关于 Timeline.js 和 Knockout.js 与 ASP.NET MVC 4 的问题。我希望我的问题实际上与有人可以发现的不当使用 Javascript 有关,因为我不太确定有多少 Timeline+ Knockout+Datepicker 的人都在外面。
我有一个包含以下内容的视图,其中包含一个 div 和一个 ajax 链接,最终使用部分视图填充该 div。
<div>Starting Order Date: <input data-bind="datepicker: StartDate, datepickerOptions: { maxDate : $.now() }" /></div>
<div id="Status"></div>
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#Status" href="/Track/Status/1">Blarg</a>
<script src="~/ViewModels/TrackModels.js"></script>
在 TrackModels.js 中,我有一个用于日期选择器的淘汰赛扩展器。为简洁起见,我删除了“更新”和 dom 处理部分,但它本质上是带有 jquery-ui datepicker 的 knockoutjs 数据绑定中的内容
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
});
}
};
由 ajax 链接返回并替换状态 div 的部分视图是
@model MyProject.Data.DTO.Timeline
<div id="timeline-embed"></div>
<script type="text/javascript">
var timeline_config = {
width: '100%',
height: '500',
source: {
"timeline":
@Html.Raw(@Json.Encode(Model))
}
}
</script>
<script type="text/javascript" src="~/scripts/js/storyjs-embed.js"></script>
现在,问题!在单击 ajax 链接之前,日期选择器可以正常工作以更新淘汰模型。单击 ajax 链接后,时间线会正确显示并显示它应该显示的内容。但是,我的日期选择器开始失败并出现错误:
TypeError: $(...).datepicker is not a function
observable($(element).datepicker("getDate"));
所以,不知何故,我最初绑定的元素正在失去它是一个日期选择器。可以....谁能告诉我为什么?将storyjs-embed部分粘贴有问题吗?我不明白...在 Firebug 中逐步执行,日期选择器仍在抛出其更改事件处理程序,但由于某种原因,它就像元素正在丢失它是一个日期选择器。感谢您的任何帮助!
编辑:
不幸的是,Jeroen 并不完全正确(我尝试了建议的更改,但仍然出现相同的错误)。但是,我发现如果我将 init 部分更改为以下内容
init: function(element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
$el.datepicker(options);
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($el.datepicker("getDate"));
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$el.datepicker("destroy");
});
},
并完全注释掉我的更新部分:
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$el = $(element);
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
var current = $el.datepicker("getDate");
if (value - current !== 0) {
$el.datepicker("setDate", value);
}
}
然后我的日期选择器在打开 Ajax 链接后不会出现同样的错误。如果我按照最初的方式离开 init 部分(没有 $el),它仍然会出现错误。