Javascript 使用Knockout.js如何将日期属性绑定到HTML5日期选择器?
(目前这只适用于Chrome,因为大多数浏览器尚未为输入type=“date”实现日期选择器) 在下面的示例中,MyDate以当前日期的日期对象开始,但日期输入不会拾取该对象(它的格式应为YYYY/MM/DD格式的字符串) 一旦在选择器中选择了日期,MyDate就会变成上面格式的字符串 如何绑定它,使MyDate保持为javascript日期,并由输入控件正确解释 见:-Javascript 使用Knockout.js如何将日期属性绑定到HTML5日期选择器?,javascript,html,knockout.js,Javascript,Html,Knockout.js,(目前这只适用于Chrome,因为大多数浏览器尚未为输入type=“date”实现日期选择器) 在下面的示例中,MyDate以当前日期的日期对象开始,但日期输入不会拾取该对象(它的格式应为YYYY/MM/DD格式的字符串) 一旦在选择器中选择了日期,MyDate就会变成上面格式的字符串 如何绑定它,使MyDate保持为javascript日期,并由输入控件正确解释 见:- var viewModel={ MyDate:ko.可观察(新日期()), 对数:ko.可观察(“”), logDate
var viewModel={
MyDate:ko.可观察(新日期()),
对数:ko.可观察(“”),
logDate:函数(){
this.log(this.log()+this.MyDate()+“:”+
typeof(this.MyDate())+“
”;
}
};
viewModel.MyDate.subscribe(函数(日期){
viewModel.logDate();
});
应用绑定(视图模型);
viewModel.logDate()
您可以为模型中的日期对象使用计算变量:
在html中:
<input data-bind="value : rawDate" type="date">
请参见演示:来自
目前有两种格式:
- 显示格式
- 暴露于JavaScript并发送到服务器的内部格式
Date
对象,以便您可以在应用程序中的其他位置读取它
如果您还想从JS向它写入数据,您可以设置并解析输入,查看它是来自输入字段的字符串,还是JS中的
Date
对象。而@amakhrov answer将起作用(如果使用@Stijn提供的sujested这样的可写计算可观察对象,效果会更好),我决定使用
这样做的主要优点是可重用性——我只需使用data bind=“datePicker:MyDate”
就可以了。我还可以修改输入元素的其他属性,这样,如果绑定到复杂的jQuery(和其他)控件,这将非常有用
(关于做这类事情的3种选择)
HTML
请参见这里有一个最新的knockoutjs解决方案,它基于下面的链接,经过修改,具有一个自定义的init函数,可以在日期值更改时更新ko.computed属性 请注意,utils.formatDate只是一个实用函数,它可以将日期格式化为您想要的任何字符串,因此无论您是使用momentjs还是其他什么,只要将其替换为您自己的日期格式化代码即可
ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
ko.utils.registerEventHandler(element, 'change', function () {
var value = valueAccessor();
if (element.value !== null && element.value !== undefined && element.value.length > 0) {
value(element.value);
}
else {
value('');
}
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var output = '';
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) {
output = utils.formatDate(valueUnwrapped);
}
if ($(element).is('input') === true) {
$(element).val(output);
} else {
$(element).text(output);
}
}
};
<div>
<label>Date of Birth:</label>
<input type="text" data-bind="date: dateOfBirth, format: 'DD MMM YYYY'" />
</div>
ko.bindingHandlers.date={
init:function(元素、valueAccessor、allBindingsAccessor、viewModel){
ko.utils.registerEventHandler(元素'change',函数(){
var value=valueAccessor();
if(element.value!==null&&element.value!==undefined&&element.value.length>0){
价值(元素价值);
}
否则{
价值(“”);
}
});
},
更新:函数(元素、valueAccessor、allBindingsAccessor、viewModel){
var value=valueAccessor();
var valueUnwrapped=ko.utils.unwrapObservable(值);
var输出=“”;
if(valueUnwrapped!==null&&valueUnwrapped!==undefined&&valueUnwrapped.length>0){
输出=utils.formatDate(valueUnwrapped);
}
if($(元素).is('input')==true){
$(元素).val(输出);
}否则{
$(元素)。文本(输出);
}
}
};
出生日期:
根据Ryan的上述回答,这对于更新的ko/chrome小部件来说效果更好。它还去除了日期的时间部分
ko.bindingHandlers.datePicker = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
// Register change callbacks to update the model
// if the control changes.
ko.utils.registerEventHandler(element, "change", function () {
var value = valueAccessor();
var target_date = element.valueAsDate;
var truncated = new Date(target_date.getFullYear(), target_date.getMonth(), target_date.getDate());
value(truncated);
});
},
// Update the control whenever the view model changes
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var unwrapped = ko.utils.unwrapObservable(value());
if(unwrapped === undefined || unwrapped === null) {
element.value = '';
} else {
element.valueAsDate = unwrapped;
}
}
};
现在使用Moment.js就容易多了
this.sessionDate = ko.observable(moment().format('YYYY-MM-DD'));
this.getFormattedDate = () => { return moment(this.sessionDate()'YYYY-MM-DD').format('MM/DD/YYYY') }; // Note this is ES2015 syntax
在html中,您可以使用
<input class="form-control" name="date" type="date" id="date" data-bind="value: sessionDate">
并将其格式化为
<p data-bind="text : getFormattedDate()">Loading Date</p>
加载日期
无需创建自定义绑定,您可以为较旧的浏览器使用垫片。与相同,但使用momentJS:
ko.bindingHandlers.datePicker = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
// Register change callbacks to update the model
// if the control changes.
ko.utils.registerEventHandler(element, "change", function () {
var value = valueAccessor();
value(moment(element.value).format());
});
},
// Update the control whenever the view model changes
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
element.value = moment(value()).format("YYYY-MM-DD");
}
};
这对我有用
ko.bindingHandlers.momentDate = {
_parseDateTime: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var datetime = moment(valueUnwrapped);
var date = moment($(element).val(), 'YYYY-MM-DD');
datetime = datetime.set({
'year': date.get('year'),
'month': date.get('month'),
'date': date.get('date')
});
value(datetime.toDate());
},
init: function (element, valueAccessor) {
function bind() {
ko.bindingHandlers.momentDate._parseDateTime(element, valueAccessor);
}
$(element).change(bind).blur(bind);
},
update: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var date = moment(valueUnwrapped);
$(element).val(date.format('YYYY-MM-DD'));
}
})
这可能已经晚了,但它可能会帮助其他人。我正在使用的
DateTime
对象轻松管理应用程序中的日期和时区。这适用于DateTime对象:
ko.bindingHandlers.dateTime={
//注册更改回调以在控件更改时更新模型。
init:函数(元素、valueAccessor、allBindingsAccessor、viewModel){
ko.utils.registerEventHandler(元素'change',函数(){
常量值=值访问器()
const datetime=datetime.fromFormat(element.value,“yyyy-MM-dd”)
值(日期时间)
})
},
//每当视图模型更改时更新控件
更新:函数(元素、valueAccessor、allBindingsAccessor、viewModel){
常量值=值访问器()
element.value=ko.unwrap(value.toFormat('yyyy-MM-dd'))
}
}
用法:
// viewmodel
const today = DateTime.fromFormat(DateTime.now().toFormat('yyyy-MM-dd'), 'yyyy-MM-dd')
this.date = ko.observable(today)
// template
<input type="date" data-bind="dateTime: date">
//视图模型
const today=DateTime.fromFormat(DateTime.now().toFormat('yyyy-MM-dd'),'yyyy-MM-dd'))
this.date=ko.可观察(今天)
//模板
在初始加载时没有设置选择器的值-必须将rawDate设置为ISO格式的MyDate字符串?你说得对。原始示例中没有显示日期,因此我忘了添加:)请查看上面更新的代码和演示。感谢您的回答,您能告诉我如何使用html5 datepicker(输入类型“date”)和knockout.js而不使用计算变量吗?就像在这里做的那样:这对你仍然有效吗?
<p data-bind="text : getFormattedDate()">Loading Date</p>
ko.bindingHandlers.datePicker = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
// Register change callbacks to update the model
// if the control changes.
ko.utils.registerEventHandler(element, "change", function () {
var value = valueAccessor();
value(moment(element.value).format());
});
},
// Update the control whenever the view model changes
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
element.value = moment(value()).format("YYYY-MM-DD");
}
};
ko.bindingHandlers.momentDate = {
_parseDateTime: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var datetime = moment(valueUnwrapped);
var date = moment($(element).val(), 'YYYY-MM-DD');
datetime = datetime.set({
'year': date.get('year'),
'month': date.get('month'),
'date': date.get('date')
});
value(datetime.toDate());
},
init: function (element, valueAccessor) {
function bind() {
ko.bindingHandlers.momentDate._parseDateTime(element, valueAccessor);
}
$(element).change(bind).blur(bind);
},
update: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var date = moment(valueUnwrapped);
$(element).val(date.format('YYYY-MM-DD'));
}
<input type="date" data-bind="momentDate: $data.Date" class="form-control"/>
// viewmodel
const today = DateTime.fromFormat(DateTime.now().toFormat('yyyy-MM-dd'), 'yyyy-MM-dd')
this.date = ko.observable(today)
// template
<input type="date" data-bind="dateTime: date">