Knockout.js 取消双向自定义绑定以在日期和时间字段中拆分ISO datetime
我在服务器端有一个日期时间字符串YYYY-MM-DDT03:00,在客户端有一个矩.js 我需要将bindinghandler的更新和初始化阶段绑定到我的observable datetime属性,但无法使其与表单输入一起工作 这是纯文本元素更新阶段的工作思路:Knockout.js 取消双向自定义绑定以在日期和时间字段中拆分ISO datetime,knockout.js,Knockout.js,我在服务器端有一个日期时间字符串YYYY-MM-DDT03:00,在客户端有一个矩.js 我需要将bindinghandler的更新和初始化阶段绑定到我的observable datetime属性,但无法使其与表单输入一起工作 这是纯文本元素更新阶段的工作思路: ko.bindingHandlers.date = { update: function(element, valueAccessor) { var options = ko.unwrap(valueAccess
ko.bindingHandlers.date = {
update: function(element, valueAccessor) {
var options = ko.unwrap(valueAccessor);
var value = ko.unwrap(options.value);
var text = moment(value).format('DD/MM/YYYY');
ko.utils.setTextContent(element, text);
},
};
ko.bindingHandlers.time = {
update: function(element, valueAccessor) {
var options = ko.unwrap(valueAccessor);
var value = ko.unwrap(options.value);
var text = moment(value).format('HH:mm');
ko.utils.setTextContent(element, text);
},
};
编辑-我尝试将我的问题背景化一点
实际上,作为一个knockout和js新手,我正在尝试将EtherogenousJSON数组从服务器映射到每个项都可以通过ko.mapping具有各种属性的knockout observates。最后,我需要一个ko可观测数组,其中包含每个原始数组项的编辑/保存/取消/删除方法
function EditableCollection(payload, updateUrl) {
/* EditableCollections = { item: actual object,
* data: actual data,
* edit, editing Knockout facility,
* }
*/
var collection = this;
collection.item = ko.mapping.fromJS(payload);
collection.editing = ko.observable(false);
collection.edit = function() {
if (!self.condition()) {
// UI logic
collection._bkp = ko.mapping.toJS(collection.item);
collection.editing(true);
} else {
// UI logic
};
};
collection.cancel = function() {
ko.mapping.fromJS(collection._bkp, collection.item);
delete(collection._bkp);
collection.editing(false);
// UI logic
};
collection.item.cancel = collection.cancel;
collection.save = function() {
if (updateUrl) {
$.ajax({
url: updateUrl,
method:'POST',
dataType:'json',
data: JSON.stringify($.extend(updateData, { 'item': ko.mapping.toJS(collection.item) })), // or something
success: function(result){
return result;
},
error: function(error){
return error;
},
});
};
// UI logic
delete(collection._bkp);
};
collection.item.save = collection.save;
};
最初的问题是因为当我面对包含ISO8601字符串的数组时,我需要在两个单独的属性date和time中进行转换
所以我想我不能使用computedProperties。作为解决原始绑定方法的一种方法,我求助于在mapping create function中管理任务,但这对我来说非常低效且难看:
var scadenzeMapping = {
create: function(options) {
var payload = options.data;
console.log(payload);
// ** moment.js:
// When refactoring for TIME will matter.
var start = moment(payload.data_start); // e.g. 05/02/2018T00:00:00
// TODO ** Verify timezone (external) handling...
if (payload.isAllDay) {
payload.sdate = start.format('DD/MM/YYYY');
payload.stime = undefined;
payload.edate = payload.sdate;
payload.etime = undefined;
payload.data_end = payload.data_start;
} else {
payload.sdate = start.format('DD/MM/YYYY');
payload.stime = start.format('HH:mm');
var end = moment(payload.data_end);
payload.edate = end.format('DD/MM/YYYY');
payload.etime = end.format('HH:mm');
};
// payload.data_start = start;
return new EditableCollection(payload,
'{{ put_event }}',
);
},
};
这是原始问题的主题外上下文。首先,您的自定义绑定不订阅传递的可观察对象的更改。如果你改变
var options = ko.unwrap(valueAccessor);
到
在传递的可观察对象发生更改后,将调用update函数
其次,如果您试图对输入使用此绑定,则不能使用
ko.utils.setTextContent(element, text);
因为它改变了元素的内容,而不是值。你需要使用
element.value = text;
我认为最好的方法是不使用自定义绑定,使用可写计算,使用标准值绑定,比如:
var myObservable = ko.observable();
var myComputed = ko.computed({
write: function(val){
myObservable(moment(val, 'DD/MM/YYYY').format('YYYY-MM-DDTHH:mm'))
},
read: function(){
return moment(myObservable()).format('DD/MM/YYYY');
}
})
在html中:
<input data-bind="value: myComputed"/>
…我想我最终会在视图模型中保留ISO格式的datetime和单独的日期和时间…几个Computed会很好地为您服务。毫无疑问,您和Ray J建议使用computedProperties是正确的,但我的问题实际上与ko.mapping有关,正如我在上面的编辑中试图解释的那样。我认为关键是在ko.bindingHandlers中使用init函数。Thanks@user2154587您不需要在ko.mapping中转换它们。您可以只存储未转换的日期,并在viewmodel中进行两次计算,将其转换为日期和时间。
<input data-bind="value: myComputed"/>