TempusDominus Knockout 绑定在初始化后不会触发更新事件
TempusDominus Knockout Binding Doesn't Fire update Event After Initializing
我正在尝试将 knockoutjs 与 tempusdominus datetimepicker 一起使用,但自定义绑定有问题。绑定将在初始化期间工作,但通过日期选择器进行的更改 ui 或不会导致更新事件由自定义绑定处理。请忽略丢失的图标,我认为这不是导致问题的原因。
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
//initialize datepicker with some optional options
var options = allBindings().datepickerOptions || {
format: 'MM/DD/YYYY HH:mm',
defaultDate: valueAccessor()()
};
$(element).datetimepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "change.datetimepicker", function(event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date);
}
console.log("change.datetimepicker"); //, event.date.format());
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var val = ko.utils.unwrapObservable(valueAccessor());
if ($(element).datetimepicker) {
$(element).datetimepicker("date", val);
}
console.log("update called"); //, $(element).datetimepicker("date").format());
}
};
var viewModel = {};
function QuoteViewModel(data) {
var self = this;
self.dt2 = ko.observable(moment());
};
viewModel = new QuoteViewModel();
ko.applyBindings(viewModel);
/*
$("#datetimepicker1").on("change.datetimepicker", function (e) {
console.log("on change", e.date.format());
});
*/
<link href="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/build/css/bootstrap-datetimepicker.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/src/js/bootstrap-datetimepicker.js"></script>
<div class="col-sm-6">
<div class="form-group">
<div class="input-group date" id="datetimepicker1" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1" data-bind="datepicker: dt2" />
<div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre> SCRIPT
https://jsfiddle.net/mh_surge/7yrze0Lv/6/
如果我取消注释底部添加非 ko 更改事件处理程序的代码,它总是会按预期触发。这让我相信 ko.utils.registerEventHandler 可能有问题,但该函数的源代码似乎没问题。
为什么 update 和 change 事件在初始化期间只触发一次,我该如何解决?
触发的更改事件不包含 event.date
属性。您注释掉 jQuery 版本的原因是它针对不同的元素。
在敲除代码中,您正在使用传递给 init
和 update
的 element
参数。这是指具有 datepicker
data-bind.
的元素
在 jQuery 代码中,您的目标是 $("#datetimepicker1")
,这是一个 <div>
,具有由插件实现的自定义 change
元素。
要解决此问题,您需要:
- 将
datepicker
绑定到 ID 为 datetimepicker1
的元素上(即 not 放在 input
元素上)
- 在
init
函数中使用$(element).on("change.datepicker", ...)
语法
- 添加一个 element disposal callback 来清理小部件实例,以防敲除从 DOM
中删除元素
以下编辑适用于日历弹出窗口和文本输入的手动编辑。
ko.bindingHandlers.dateTimePicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().dateTimePickerOptions || {};
var initialValue = ko.utils.unwrapObservable(valueAccessor());
if (initialValue) {
options.date = initialValue;
}
$(element).datetimepicker(options);
ko.utils.registerEventHandler(element, "change.datetimepicker", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date || event.target.value || null);
}
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datetimepicker("destroy");
});
},
update: function (element, valueAccessor) {
var val = ko.utils.unwrapObservable(valueAccessor());
console.log(arguments, val);
if ($(element).datetimepicker) {
$(element).datetimepicker("date", val);
}
}
};
我正在尝试将 knockoutjs 与 tempusdominus datetimepicker 一起使用,但自定义绑定有问题。绑定将在初始化期间工作,但通过日期选择器进行的更改 ui 或不会导致更新事件由自定义绑定处理。请忽略丢失的图标,我认为这不是导致问题的原因。
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
//initialize datepicker with some optional options
var options = allBindings().datepickerOptions || {
format: 'MM/DD/YYYY HH:mm',
defaultDate: valueAccessor()()
};
$(element).datetimepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "change.datetimepicker", function(event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date);
}
console.log("change.datetimepicker"); //, event.date.format());
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var val = ko.utils.unwrapObservable(valueAccessor());
if ($(element).datetimepicker) {
$(element).datetimepicker("date", val);
}
console.log("update called"); //, $(element).datetimepicker("date").format());
}
};
var viewModel = {};
function QuoteViewModel(data) {
var self = this;
self.dt2 = ko.observable(moment());
};
viewModel = new QuoteViewModel();
ko.applyBindings(viewModel);
/*
$("#datetimepicker1").on("change.datetimepicker", function (e) {
console.log("on change", e.date.format());
});
*/
<link href="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/build/css/bootstrap-datetimepicker.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/src/js/bootstrap-datetimepicker.js"></script>
<div class="col-sm-6">
<div class="form-group">
<div class="input-group date" id="datetimepicker1" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1" data-bind="datepicker: dt2" />
<div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre> SCRIPT
https://jsfiddle.net/mh_surge/7yrze0Lv/6/
如果我取消注释底部添加非 ko 更改事件处理程序的代码,它总是会按预期触发。这让我相信 ko.utils.registerEventHandler 可能有问题,但该函数的源代码似乎没问题。
为什么 update 和 change 事件在初始化期间只触发一次,我该如何解决?
触发的更改事件不包含 event.date
属性。您注释掉 jQuery 版本的原因是它针对不同的元素。
在敲除代码中,您正在使用传递给 init
和 update
的 element
参数。这是指具有 datepicker
data-bind.
在 jQuery 代码中,您的目标是 $("#datetimepicker1")
,这是一个 <div>
,具有由插件实现的自定义 change
元素。
要解决此问题,您需要:
- 将
datepicker
绑定到 ID 为datetimepicker1
的元素上(即 not 放在input
元素上) - 在
init
函数中使用$(element).on("change.datepicker", ...)
语法 - 添加一个 element disposal callback 来清理小部件实例,以防敲除从 DOM 中删除元素
以下编辑适用于日历弹出窗口和文本输入的手动编辑。
ko.bindingHandlers.dateTimePicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().dateTimePickerOptions || {};
var initialValue = ko.utils.unwrapObservable(valueAccessor());
if (initialValue) {
options.date = initialValue;
}
$(element).datetimepicker(options);
ko.utils.registerEventHandler(element, "change.datetimepicker", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date || event.target.value || null);
}
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datetimepicker("destroy");
});
},
update: function (element, valueAccessor) {
var val = ko.utils.unwrapObservable(valueAccessor());
console.log(arguments, val);
if ($(element).datetimepicker) {
$(element).datetimepicker("date", val);
}
}
};