我正在使用Knockout JS和使用VB.NET的Web服务构建一个小表单,Web服务是采用三个字符串(名字,姓氏和雇用日期并保存到数据库)我已经测试了webservice在常规的JavaScript上它工作正常,但不是我试图使用Knockout JS来做同样的功能。
问题是使用ko.observable等待值的对象没有接收到任何值,因此将null对象发送到Web服务。
这是脚本
<script type="text/javascript">
var viewModel = function (f,n,h) {
var self = this;
this.fName = ko.observable(f);
this.lName = ko.observable(n);
this.hDate = ko.observable(h);
self.savePerson = function () {
alert("savePerson");
var person = {
FirstName: self.fName,
LastName: self.lName,
HireDate: self.hDate
};
var DTO = { 'Instructor1': person };
$.ajax({
type: "POST",
data: JSON.stringify(DTO), //JSON.stringify(DTO),
url: "POSTHandler.asmx/SaveInstructor",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert("sucess")
OnSaveInstructorAjaxSucceeded(result);
},
error: function (result) {
alert("error");
}
});
function OnSaveInstructorAjaxSucceeded(result) {
alert(result);
}
function OnSaveInstructorAjaxFailed(xhr, textStatus, error) {
alert("Error occured while getting attendees, Error Code: " + xhr.status + ". Error desc: " + xhr.statusText);
}
}
}
$(document).ready(function () {
var _vm = new viewModel("f","n","h");
ko.applyBindings(_vm);
});
</script>
这是html
<asp:Label ID="Label1" runat="server" Text="First Name "></asp:Label>
<input type="text" id="fname1" data-bind="value: $root.fName()" style="margin-left: 28px" />
<br />
<br />
<asp:Label ID="Label2" runat="server" style="z-index: 1; left: 11px; top: 56px; position: absolute" Text="Last Name"></asp:Label>
<input type="text" id="lname1" data-bind="value: $root.lName()" style="z-index: 1; left: 107px; position: absolute" />
<br />
<asp:Label ID="Label3" runat="server" style="z-index: 1; left: 12px; top: 98px; position: absolute" Text="Hire Date"></asp:Label>
<br />
<input type="text" id="hdate1" data-bind="value: $root.hDate()" style="z-index: 1; left: 104px; top: 98px; position: absolute" />
<br />
<br />
<br />
<%--<button id="Button1" data-bind="click: $root.savePerson" style="width: 52px" >save</button>--%>
<input type="button" value="Save" data-bind="click: savePerson" />
</div>
<label id="Label4" data-bind="text: $root.fName" ></label>
</form>
答案 0 :(得分:1)
双向数据绑定在您的情况下不起作用,因为您已将它们定义错误。在html中,您希望将输入的值绑定到observable而不是可观察的结果。
你这样做:
<input type="text" data-bind="value: $root.fName()" />
但你应该这样做:
<input type="text" data-bind="value: $root.fName" /> -- Note the missing parenthesis
但是,这只是问题的一部分。另一个问题是您的视图模型包含observables
,它们是作为函数实现的,因此不会使用JSON.stringify
进行序列化。
解决此问题的最简单方法是使用ko.toJS
和JSON.stringify
或ko.toJSON
。
ko.toJS
将遍历对象图并生成一个干净的副本,其属性等同于observable,而ko.toJSON
将在内部调用ko.toJS
,然后将使用浏览器的本机JSON序列化程序。
所以在你的情况下你可以尝试:
var DTO = {
Instructor1: {
FirstName: self.fName,
LastName: self.lName,
HireDate: self.hDate
}
};
$.ajax({
type: "POST",
data: ko.toJSON(DTO),
url: "POSTHandler.asmx/SaveInstructor",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert("sucess")
},
error: function (result) {
alert("error");
}
});
或者你可以在没有任何帮助的情况下手动完成工作:
var DTO = {
Instructor1: {
FirstName: self.fName(), // Note the parenthesis
LastName: self.lName(), // Note the parenthesis
HireDate: self.hDate() // Note the parenthesis
}
};
$.ajax({
type: "POST",
data: JSON.stringify(DTO),
url: "POSTHandler.asmx/SaveInstructor",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert("sucess")
},
error: function (result) {
alert("error");
}
});
为了便于序列化视图模型数据,包括observable等,Knockout包含两个辅助函数:
ko.toJS
- 这会克隆你的视图模型的对象图,用每个observable替换该observable的当前值,这样你就得到一个只包含你的数据而没有Knockout相关工件的普通副本
ko.toJSON
- 这会生成一个表示视图模型数据的JSON字符串。在内部,它只是在视图模型上调用ko.toJS,然后在结果上使用浏览器的本机JSON序列化程序。注意:为了在没有本机JSON序列化程序的旧浏览器(例如,IE 7或更早版本)上工作,您还必须引用json2.js库。