1

我有一个关于 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),它仍然会出现错误。

4

0 回答 0