Jack
Jack

Reputation: 10047

How do you update a KnockOutJs ViewModel from a jquery ajax call?

As you can see from the snippet. I want to update the ViewModel's isShowMsg and showMessageValue after the btnSumbit click. The controller on MVC is basically return a json (fullName). How do I update a viewmodel that's already bind from jquery ajax call?

<script type="text/javascript">

    $(document).ready(function () {

        var ViewModel = function (first, last, isshowmsg, showmsg) {
            this.firstName = ko.observable(first);
            this.lastName = ko.observable(last);
            this.isShowMsg = ko.observable(isshowmsg);
            this.showMessageValue = ko.observable(showmsg);
        };
                                      
        $("#btnSubmit").click(function () {

            var firstName = $("#txtFirstName").val();
            var lastName = $("#txtLastName").val();

            $.ajax({
                url: '@Url.Action("Submit","Home")',
                type: "POST",
                data: { firstName: firstName, lastName: lastName },
                dataType: "json",
                success: function (response) {                    
                    if(response.fullName != undefined || response.fullName != null)
                    {
                        ViewModel.isShowMsg = true;
                        ViewModel.showMessage = response.fullName;                        
                    }
                }
            });
        });

        ko.applyBindings(new ViewModel("Planet", "Earth", false, ""));
        
    });

</script>
<style>
    body { font-family: arial; font-size: 14px; }
    .liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
    .liveExample input { font-family: Arial; }
    .liveExample b { font-weight: bold; }
    .liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
    .liveExample select[multiple] { width: 100%; height: 8em; }
    .liveExample h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
</style>
<div class="col-md-12">

            <div class='liveExample'>
                <p>First name: <input id="txtFirstName" data-bind='value: firstName' /></p>
                <p>Last name: <input id="txtLastName" data-bind='value: lastName' /></p>                
                <label id="lblResult" data-bind="visible: isShowMsg, value: showMessageValue"></label>
            </div>

            <button id="btnSubmit">Submit</button>

        </div>

Upvotes: 0

Views: 488

Answers (2)

Zbrr
Zbrr

Reputation: 11

Try like this:

ViewModel.isShowMsg(true);
ViewModel.showMessage(response.fullName);

See the docs on observables

Upvotes: 0

Roy J
Roy J

Reputation: 43899

You need to let go of jQuery to write good Knockout code. If you are using a jQuery selector, you're probably doing something wrong. See the click binding docs for how to handle click events. The Knockout tutorial is also well worth your time.

You have created a constructor function ViewModel for your view model, but then you treat it like it's the view model itself. ViewModel.isShowMessage does not exist. You need to assign the view model to a variable so you can refer to it. Also, observables are setter/getters. To assign a value, you need to pass it as an argument.

var vm = new ViewModel("Planet", "Earth", false, "");
ko.applyBindings(vm);
...and elsewhere...
vm.isShowMessage(true);

Upvotes: 2

Related Questions