1
votes

I'm going to end up with multiple viewModels on the same page so I'm trying to figure out how to pass the viewModel as a variable to a function in order to do my ajax calls. I'm trying to update this span:

<span data-bind="text: AnswerText"/></span> <span data-bind="text: GetFormattedDate() "/></span>

This chunk of code works and correctly populates with a value from GetFormattedDate:

var viewModel1;
$(document).ready(function () {
    var jsonDataToSend = { questionConfigurationID: 1 };
    $.ajax({
        url: "SomePage.aspx/GetAnswerAndComments",
        type: "post",
        dataType: "text json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(jsonDataToSend),
        success: function (msg) {
            var result = msg.d;
            if (result != null) {
               viewModel1 = ko.mapping.toJS(result);
                ko.applyBindings(viewModel1, document.getElementById("divAnswerAndComment1"));
            }
        }
    });

});


function GetFormattedDate()
{
    var date = "";
    if (viewModel1.InsertDate != null) 
    {
        date = new Date(parseInt(viewModel1.InsertDate.substr(6)))
    } 
    return date;
} 

But when I replaced the $document.ready function with a call to another function passing the viewModel as a variable when GetFormattedDate is called viewModel1 is undefined (see below). I'm pretty sure it has something to do with the scope of the viewModel1 but I can't figure out exactly what the issue is.

var viewModel1;
$(document).ready(function () {
GetAnswersAndComments(1, viewModel1);
});


function GetAnswersAndComments(questionID, currentViewModel) {
    var jsonDataToSend = { questionConfigurationID: questionID };
    $.ajax({
        url: "ControlWebMethods.aspx/GetAnswerAndComments",
        type: "post",
        dataType: "text json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(jsonDataToSend),
        success: function (msg) {
            var result = msg.d;
            if (result != null) {
                currentViewModel = ko.mapping.toJS(result);
                ko.applyBindings(currentViewModel);
            }
        }
    });        
}

function GetFormattedDate()
{
    var date = "";
    if (viewModel1.InsertDate != null) 
    {
        date = new Date(parseInt(viewModel1.InsertDate.substr(6)))
    } 
    return date;
} 
1
You really shouldn't applyBindings inside a function like that. apply once, then push changes to your viewmodel. The binding will keep the view up to date.Kyeotic
I'm not sure I understand what you mean.mistyayn
The call to ko.applyBindings() should only ever at once. Once the bindings are applied, any HTML with data-binding will get updated when the viewmodel is updated. If this still doesn't make sense, please consider going through the Knockout tutorials.Kyeotic
Okay I think that makes sense. But even if I move ko.ApplyBindings() outside the function it still doesn't change the fact that I can't access the viewModel from inside GetFormattedDate().mistyayn
Yeah, and as soon as jsfiddle is back up I will look into that, but even if you get this working its a very fragile design. Knockout is intended to be used with an MVVM pattern; these functions should be on the viewmodel. Proper design would go a long way to keeping these problems from cropping up.Kyeotic

1 Answers

0
votes

You're passing viewModel1 to GetAnswersAndComments. Inside the function you have a local copy of the reference to viewModel1, and this local copy is called currentViewModel.

You then set that local variable with currentViewModel = ko.mapping.toJS(result);. This doesn't touch viewModel1 and so it remains undefined. Basic Javascript