我在表单中使用Asp.Net MVC 4和Knockout。
我有一个我希望格式化的日期输入。
我最终得到了这个解决方案: http://jason-mitchell.com/web-development/binding-dates-using-knockout-moment-js/
我的问题是,当我提交表单时,我没有在发布的JSON中填写日期。
我认为问题出在自定义处理程序中,但我无法找到:( 更新事件仅在加载时触发一次。
查看代码
@Html.TextBoxFor(Function(model) model.EndDate, New With {.data_bind = "date: EndDate"})
自定义绑定代码
ko.bindingHandlers.date = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var allBindings = allBindingsAccessor();
// Date formats: http://momentjs.com/docs/#/displaying/format/
var pattern = allBindings.format || 'L';
var output = "";
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) {
output = moment(valueUnwrapped).format(pattern);
}
if ($(element).is("input") === true) {
$(element).val(output);
} else {
$(element).text(output);
}
}
};
ko binding Code
var viewModel = ko.mapping.fromJS(@Html.Raw(Model.ToJson()));
ko.applyBindings(viewModel);
注意:日期格式正如期望的那样。
我做错了什么? :(
答案 0 :(得分:2)
没有看到你的ViewModel,我只能推测。在您的代码中,您将EndDate直接绑定到TextBox:
@Html.TextBoxFor(Function(model) model.EndDate, New With {.data_bind = "date: EndDate"})
您的EndDate observable对此值一无所知。因此,如果您的EndDate observable在ViewModel中看起来像这样:
this.EndDate = ko.observable();
然后它不知道ASP.NET MVC代码直接绑定到TextBox的值。因此,当您应用KO绑定时,直接绑定到TextBox的EndDate值将被销毁。如果是这种情况,您可以:(1)直接从服务器Model绑定的值初始化EndDate observable,或者(2)使用自定义KO绑定间接初始化EndDate observable,该绑定初始化EndDate observable直接绑定到TextBox的值。
示例1
此示例假定JavaScript直接位于您的视图中。如果您的JavaScript位于单独的文件中(通常就是这种情况),那么在绑定ViewModel之前,您必须使用客户端上的JSON序列化等其他技术将Model数据传递到ViewModel。
this.EndDate = ko.observable('@Model.EndDate.ToString()');
示例2
在此示例中,KO绑定参数的顺序很重要。新的自定义绑定必须是第一个绑定才能使其正常工作:
@Html.TextBoxFor(Function(model) model.EndDate, New With {.data_bind = "initInputFromView: EndDate, date: EndDate"})
以下是自定义KO绑定的代码:
ko.bindingHandlers.initInputFromView = {
init: function (element, valueAccessor) {
// reads the value stored in the <input> value attribute and initializes the observable with that value
valueAccessor()(element.value);
}
};
答案 1 :(得分:1)
最后,我找到了解决方案!
自定义绑定应如下所示:
ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.bindingHandlers.value.init(element, valueAccessor,
allBindingsAccessor, viewModel, bindingContext);
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var allBindings = allBindingsAccessor();
// Date formats: http://momentjs.com/docs/#/displaying/format/
var pattern = allBindings.format || 'L';
var output = valueUnwrapped;
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) {
output = moment(valueUnwrapped).format(pattern);
}
if ($(element).is("input") === true) {
$(element).val(output);
} else {
$(element).text(output);
}
},
};
它使用默认值绑定加上我的自定义日期格式。 仅在init上,因为更新由正确格式化的datepicker管理。