在Knockout JS中没有收到任何值

时间:2015-10-04 06:56:43

标签: javascript html asp.net knockout.js

我正在使用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" />

    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
         <br />
         <br />
         <br />
         &nbsp;


  <%--<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>

1 个答案:

答案 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.toJSJSON.stringifyko.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");
    }
});

这是JsFiddle Demo

来自knockout documentation

  

为了便于序列化视图模型数据,包括observable等,Knockout包含两个辅助函数:

     

ko.toJS - 这会克隆你的视图模型的对象图,用每个observable替换该observable的当前值,这样你就得到一个只包含你的数据而没有Knockout相关工件的普通副本

     

ko.toJSON - 这会生成一个表示视图模型数据的JSON字符串。在内部,它只是在视图模型上调用ko.toJS,然后在结果上使用浏览器的本机JSON序列化程序。注意:为了在没有本机JSON序列化程序的旧浏览器(例如,IE 7或更早版本)上工作,您还必须引用json2.js库。