jQuery UI에서 KnockoutJS를 사용하려고합니다. 날짜 선택기가 첨부 된 입력 요소가 있습니다. 현재 실행 중이며 knockout.debug.1.2.1.js
변경 이벤트가 Knockout에 걸리지 않는 것 같습니다. 요소는 다음과 같습니다.
<input type="text" class="date" data-bind="value: RedemptionExpiration"/>
valueUpdate
이벤트 유형 변경을 시도 했지만 아무 소용이 없습니다. Chrome이 focus
값을 변경하기 직전 에 이벤트를 일으키는 것처럼 보이지만 IE는 그렇지 않습니다.
“모든 바인딩을 리 바인딩하는”녹아웃 방법이 있습니까? 기술적으로 서버로 다시 보내기 전에 변경된 값만 있으면됩니다. 그래서 나는 그런 종류의 해결 방법으로 살 수있었습니다.
문제는 datepicker의 잘못이라고 생각하지만이 문제를 해결하는 방법을 알 수 없습니다.
어떤 아이디어?
답변
jQuery UI datepicker의 경우 datepicker에서 제공하는 API를 사용하여 Date 객체로 읽고 쓰는 사용자 정의 바인딩을 사용하는 것이 좋습니다.
바인딩은 다음과 같습니다 ( 여기서 내 대답 에서 ).
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
$el.datepicker(options);
//handle the field changing by registering datepicker's changeDate event
ko.utils.registerEventHandler(element, "changeDate", function () {
var observable = valueAccessor();
observable($el.datepicker("getDate"));
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$el.datepicker("destroy");
});
},
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$el = $(element);
//handle date data coming via json from Microsoft
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);
}
}
};
당신은 그것을 다음과 같이 사용할 것입니다 :
<input data-bind="datepicker: myDate, datepickerOptions: { minDate: new Date() }" />
여기 jsFiddle의 샘플 : http://jsfiddle.net/rniemeyer/NAgNV/
답변
다음은 RP Niemeyer의 답변 버전입니다. http://github.com/ericmbarnard/Knockout-Validation
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).val());
if (observable.isValid()) {
observable($(element).datepicker("getDate"));
$(element).blur();
}
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datepicker("destroy");
});
ko.bindingHandlers.validationCore.init(element, valueAccessor, allBindingsAccessor);
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
//handle date data coming via json from Microsoft
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
current = $(element).datepicker("getDate");
if (value - current !== 0) {
$(element).datepicker("setDate", value);
}
}
};
변경 이벤트 핸들러는 날짜가 아닌 입력 한 값을 유효성 검증 스크립트에 먼저 전달한 다음 유효 할 경우 관찰 가능 항목으로 날짜 만 설정하도록 변경됩니다. 또한 여기에 설명 된 사용자 정의 바인딩에 필요한 validationCore.init를 추가했습니다.
http://github.com/ericmbarnard/Knockout-Validation/issues/69
또한 변경에 대한 rpenrose의 제안을 추가하여 성가신 날짜 선택기 시나리오를 제거합니다.
답변
다른 접근법을 사용했습니다. knockout.js는 변경시 이벤트를 발생시키지 않는 것이므로 datepicker가 입력을 닫을 때 change ()를 호출하도록 강요했습니다.
$(".date").datepicker({
onClose: function() {
$(this).change(); // Forces re-validation
}
});
답변
이 모든 대답이 저에게 많은 작업을 절약 해 주었지만 그 중 어느 것도 나를 위해 완전히 효과가 없었습니다. 날짜를 선택한 후에는 바인드 된 값이 업데이트되지 않습니다. 키보드를 사용하여 날짜 값을 변경 한 다음 입력 상자를 클릭 할 때만 업데이트 할 수 있습니다. 나는 이것을 얻기 위해 syb의 코드로 RP Niemeyer의 코드를 보강하여 이것을 고쳤다.
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
var funcOnSelectdate = function () {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
}
options.onSelect = funcOnSelectdate;
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", funcOnSelectdate);
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datepicker("destroy");
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (typeof(value) === "string") { // JSON string from server
value = value.split("T")[0]; // Removes time
}
var current = $(element).datepicker("getDate");
if (value - current !== 0) {
var parsedDate = $.datepicker.parseDate('yy-mm-dd', value);
$(element).datepicker("setDate", parsedDate);
}
}
};
observable ($ (element) .datepicker ( “getDate”)); 자체 기능으로 문장을 작성하고 options.onSelect에 등록하면 트릭이 수행됩니까?
답변
이 기사에 감사드립니다. 매우 유용하다는 것을 알았습니다.
DatePicker가 JQuery UI 기본 동작과 똑같이 동작하도록하려면 change 이벤트 핸들러에서 요소에 흐림 효과를 추가하는 것이 좋습니다.
즉
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
$(element).blur();
});
답변
포함 된 스크립트 파일의 순서를 변경하여이 문제를 해결했습니다.
<script src="@Url.Content("~/Scripts/jquery-ui-1.10.2.custom.js")"></script>
<script src="@Url.Content("~/Scripts/knockout-2.2.1.js")"></script>
답변
RP Niemeyer와 동일하지만 WCF DateTime, 시간대 및 DatePicker onSelect JQuery 속성 사용에 대한 지원이 향상되었습니다.
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
var funcOnSelectdate = function () {
var observable = valueAccessor();
var d = $(element).datepicker("getDate");
var timeInTicks = d.getTime() + (-1 * (d.getTimezoneOffset() * 60 * 1000));
observable("/Date(" + timeInTicks + ")/");
}
options.onSelect = funcOnSelectdate;
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", funcOnSelectdate);
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datepicker("destroy");
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
//handle date data coming via json from Microsoft
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
current = $(element).datepicker("getDate");
if (value - current !== 0) {
$(element).datepicker("setDate", value);
}
}
};
즐겨 🙂