knockout observable array动态添加的元素值为null

时间:2016-02-04 20:30:14

标签: asp.net-mvc knockout.js view

我有一个视图,可以在按钮点击时复制控件。我通过KO的observableArray实现了这个目标。我现在面临的问题是它确实复制了所有控件,但是当我尝试在保存时获取该可观察数组时,它没有所有元素。我正在尝试更新文本更改为phnumber的hiddenfor元素的值。它对第一个完全正常,但是当我点击添加新的电话号码并输入值时,除了下拉值和备注之外它都是空的。检查下面 [{ “IsDomestic”: “正确”, “COUNTRYCODE”: “1”, “AREACODE”: “201”, “******中国”: “5555555”, “InternationalNumber”: “”, “扩展”: “55”,”注释 “:” 测试”, “PrimaryNumberYN”: “错误”, “OkToId”: “NULL”, “OkToLeaveMessageYN”: “错误”, “phoneTypeDscId”:74},{ “注释”: “teststestststt”, “phoneTypeDscId” :73}]

以下是我的代码

<script type="text/javascript">
    var i = 1;
 //   var temp = @Html.Raw(Json.Encode(Model));
 //   console.log(temp);
    function PhoneTypeViewModel() {
        this.PhoneType = ko.observable();
        this.selectedPhoneType = ko.observable();
        var newPhone = function () {
            return {
                PhoneID: ko.observable(),
                IsDomestic: ko.observable(),
                CountryCode: ko.observable(),
                AreaCode: ko.observable(),
                PhoneNumber: ko.observable(),
                InternationalNumber: ko.observable(),
                Extension: ko.observable(),
                Notes: ko.observable(),
                PrimaryNumberYN: ko.observable(),
                OkToId: ko.observable(),
                OkToLeaveMessageYN: ko.observable(),
                phoneTypeDscId: ko.observable()
            }
        };
        this.multiplePhone = ko.observableArray([newPhone()]);
        //this.multiplePhone = ko.ko.observable(),([{
        //    PhoneID: 1,
        //    IsDomestic: "",
        //    CountryCode: "",
        //    AreaCode: "",
        //    PhoneNumber: "",
        //    InternationalNumber: "",
        //    Extension: "",
        //    Notes: "",
        //    PrimaryNumberYN: "False",
        //    OkToId: "False",
        //    OkToLeaveMessageYN: "False",
        //    phoneTypeDscId: ""
        //    //  visible : false
        //}]);
        this.addPhone = function () {
            i = i + 1;
            // this.multiplPhone.push(newPhone());
            this.multiplePhone.push({
                PhoneID: ko.observable(),
                IsDomestic: ko.observable(),
                CountryCode: ko.observable(),
                AreaCode: ko.observable(),
                PhoneNumber: ko.observable(),
                InternationalNumber: ko.observable(),
                Extension: ko.observable(),
                Notes: ko.observable(),
                PrimaryNumberYN: ko.observable(),
                OkToId: ko.observable(),
                OkToLeaveMessageYN: ko.observable(),
                phoneTypeDscId: ko.observable()
            });
            //this.multiplePhone.push(
            //   {
            //       //id: i, visible: true
            //       PhoneID: i,
            //       IsDomestic: "",
            //       CountryCode: "",
            //       AreaCode: "",
            //       PhoneNumber: "",
            //       InternationalNumber: "",
            //       Extension: "",
            //       Notes: "",
            //       PrimaryNumberYN: "False",
            //       OkToId: "False",
            //       OkToLeaveMessageYN: "False",
            //       phoneTypeDscId: ""
            //       //  visible : true
            //   }
            //    );
            // console.log(this.multiplePhone()[0]['PhoneID']);
        };
        this.removePhone = function (data) {
            this.multiplePhone.remove(data);
        };
        this.intlTelInpt = function () {
            console.log("test");
            this.intlTelInput({
                autoFormat: true,
                allowExtensions: true,
                utilsScript: "../../Scripts/IntlTelInput/utils.js"
            });
        };
        this.save = function () {
            console.log(ko.toJSON(this.multiplePhone));
            $.ajax({
                url: '@Url.Action("addPhone", "Patients")',
                type: "POST",
                data: ko.toJSON(this.multiplePhone),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    console.log(data);
                    alert("Phone successfully added.");
                    $('#phNumber').val("").change();
                    $('#phTypeSelect').val("").change();
                    $('#notes').val("").change();

                    //this.multiplePhone.removeAll();
                   // ko.applyBindings(new PhoneTypeViewModel());
                },
                error: function (data) {
                    console.log(data);
                    alert("An error has occurred.");
                }
            });
        }
    }
    $(document).ready(function () {
        $(window).load(function () {
            //$(document).on(".intltelinput", function () {
            //    $(this).intlTelInput({
            //        autoFormat: true,
            //        allowExtensions: true,
            //        utilsScript: "../../Scripts/IntlTelInput/utils.js"
            //    });
            //});

            //ko.applyBindings(new multiplePhonesViewModel(), document.getElementById("phoneInfo"));
            //$(document).on('click', ".remove", function () {
            //    console.log("Entered remove function");
            //    i = i - 1;
            //    $(this).closest("div.dynamicTel").remove();

            //});

            $(document).on('focus', "input.phNumber", function () {
                $(this).intlTelInput({
                    autoFormat: true,
                    allowExtensions: true,
                    utilsScript: "../../Scripts/IntlTelInput/utils.js"
                });
            });



            $.ajax({
                url: '@Url.Action("getDescriptorListByType", "Descriptor")',
                data: {type : "Phone"},
                type: "POST",
                success: function (data) {
                    var phoneTypeViewModel = new PhoneTypeViewModel();
                    phoneTypeViewModel.PhoneType(data);
                    ko.applyBindings(phoneTypeViewModel);

                }
            });

            @*$.ajax({`enter code here`
                url: '@Url.Action("getPhoneById", "Phone")',
                data: {Id : -1},
                type: "POST",
                success: function (phone) {
                    var phoneTypeVM = new PhoneTypeViewModel();
                    phoneTypeVM.multiplePhone(phone);
                   console.log(phoneTypeVM);
                }
            });*@
            // $(function () {

            //     $("#phNumber").intlTelInput({
            //         autoFormat: true,
            //         allowExtensions: true,
            //         utilsScript: "../../Scripts/IntlTelInput/utils.js"
            //     });

            //});
            $(document).on('change', "input.phNumber", function () {
                //$('#phNumber').change(function () {
                if ($(this).intlTelInput("isValidNumber") == false) {
                    var err = $('#phNumber').intlTelInput("getValidationError");
                    console.log($('#phNumber').intlTelInput("getValidationError"));
                    console.log(intlTelInputUtils.validationError);
                    switch (err) {
                        case intlTelInputUtils.validationError.INVALID_COUNTRY_CODE:
                            alert("The country code is not valid");
                            $("#error-msg").val("The country code is not valid");

                            break;

                        case intlTelInputUtils.validationError.TOO_SHORT:
                            alert("The phone number is too short");
                            $("#error-msg").val("The phone number is too short");

                            break;

                        case intlTelInputUtils.validationError.TOO_LONG:
                            alert("The phone number is too long");
                            $("#error-msg").val("The phone number is too long");

                            break;

                        case intlTelInputUtils.validationError.NOT_A_NUMBER:
                            alert("The value is not a number");
                            $("#error-msg").val("The value is not a number");

                            break;

                        default:
                            alert("The phone number is not valid");
                            $("#error-msg").val("The phone number is not valid");

                            break;
                    }
                    $("#error-msg").removeClass("hide");
                }
                else
                {
                    $('#primaryNumber').val("False").change();
                    $('#okToID').val("NULL").change();
                    $('#okToLeaveMessage').val("False").change();
                    $('#extension').val("").change();
                    $('#isDomestic').val("True").change();
                    $('#areaCode').val("").change();
                    $('#number').val("").change();
                    $('#intlNumber').val("").change();

                    var countryCode = $('#phNumber').intlTelInput("getSelectedCountryData").dialCode;
                    $('#countryCode').val(countryCode).change();
                    $('#extension').val($('#phNumber').intlTelInput("getExtension")).change();


                    if (countryCode == "1")
                    {
                        $('#number').val(($('#phNumber').intlTelInput("getNumber", intlTelInputUtils.numberFormat.NATIONAL).substring(6, 14)).replace('-','')).change();
                        $('#areaCode').val(($('#phNumber').intlTelInput("getNumber", intlTelInputUtils.numberFormat.NATIONAL)).substring(1, 4)).change();
                    }
                    else
                    {
                        $('#intlNumber').val($('#phNumber').intlTelInput("getNumber")).change();
                        $('#isDomestic').val("False").change();

                    }
                    console.log("country code = " + countryCode);
                    console.log("extension = " + $('#extension').val());
                    console.log("is domestic = " +  $('#isDomestic').val());
                    console.log("number = " + $('#number').val());
                    console.log("area code = " + $('#areaCode').val());
                    console.log("international number" + $('#intlNumber').val());

                }
            });

        });
    });

</script>

@Html.ValidationSummary(false, "", new { @class = "text-danger" })
<div i class="row" data-bind="foreach: multiplePhone">
    <div class="row">
        <div class="col-md-3">
            <div class="form-group">
                @Html.Label("Phone Number ")
                @Html.TextBox("phNumber", "", new { @id = "phNumber", type = "tel", @class = "form-control input-sm phNumber" })
                @Html.HiddenFor(model => model.PhoneNumber,new { @id = "number", @data_bind = "value:  PhoneNumber" })
                @Html.HiddenFor(model => model.IsDomestic, new { @id = "isDomestic" , @data_bind = "value: IsDomestic" })
                @Html.HiddenFor(model => model.CountryCode, new { @id = "countryCode", @data_bind = "value: CountryCode" })
                @Html.HiddenFor(model => model.AreaCode, new { @id = "areaCode", @data_bind = "value:  AreaCode" })
                @Html.HiddenFor(model => model.InternationalNumber, new { @id = "intlNumber", @data_bind = "value: InternationalNumber" })
                @Html.HiddenFor(model => model.Extension, new { @id = "extension", @data_bind = "value: Extension" })
                @Html.HiddenFor(model => model.PrimaryNumberYN, new { @id = "primaryNumber", @data_bind = "value: PrimaryNumberYN" })
                @Html.HiddenFor(model => model.OkToId, new { @id = "okToID", @data_bind = "value: OkToId" })
                @Html.HiddenFor(model => model.OkToLeaveMessageYN, new { @id = "okToLeaveMessage", @data_bind = "value: OkToLeaveMessageYN" })
                @*<input type="tel" class="form-control input-sm phNumber">*@
            </div>
        </div>
        <div class="col-md-3">
            <div class="form-group">
                @Html.Label("Phone Type ")
                @Html.DropDownListFor(model => model.phoneTypeDscId, Enumerable.Empty<SelectListItem>(), new { @class = "form-control", id = "phTypeSelect", @data_bind = "options: $parent.PhoneType, optionsValue:'DescriptorId', optionsText: 'Name', optionsCaption: '-- Choose Phone Type --', value: phoneTypeDscId" })
                @*<select class="dropdown" data-bind="options: $parent.PhoneType, optionsValue:'DescriptorId', optionsText: 'Name', optionsCaption: '-- Choose Phone Type --'"></select>*@
                @Html.ValidationMessageFor(model => model.phoneTypeDscId, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="col-md-5">
            <div class="form-group">
                @Html.Label("Notes ")
                @Html.EditorFor(model => model.Notes, new { htmlAttributes = new {id="notes", @class = "form-control input-sm", @data_bind = "value: Notes" } })
                @Html.ValidationMessageFor(model => model.Notes, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="col-md-1">
            <div class="form-group">
                <br />
                <button data-bind="click: $parent.removePhone.bind($parent), clickBubble: false, visible: $index() > 0"><span class="glyphicon glyphicon-trash"></span></button>
                @*<label data-bind="visible: visible">Remove</label>*@
            </div>
        </div>
    </div>

</div>
<div class="row">
    <div class="col-md-12">
        <div class="form-group">
            <button data-bind="click: addPhone, clickBubble: false"><span class="glyphicon glyphicon-plus"></span></button>
            <label>Add New Phone Number</label>
        </div>
    </div>
</div>

@*<div class="row">
        <div class="col-md-12">
            <button class="btn btn-default save">Save</button>
        </div>
    </div>*@

@*<div class="row">
        @Html.HiddenFor(model => model.InternationalNumber, new { htmlAttributes = new { @id = "internationalPhoneNumber"} })
    </div>*@
<div>
       <div class="col-md-3">

           <input type="submit" value="Add Phone" data-bind="click: save"  class="btn btn-default" />
        </div>
    </div>

1 个答案:

答案 0 :(得分:0)

问题在于每次点击添加新电话号码按钮时元素ID都是相同的。我必须确保为每个人分配了一个唯一的ID。我只是将数组索引附加到每个元素的id,它给了我所有的数据。 attr:{id:'areaCode'+ $ index()}