Reputation: 1419
i am trying to understand what is the best practice for defining and organizing my js viewmodels with knockout. I am not js genius so...
Ok so in many of the examples the viewModel is defined as:
var viewModel = {
firstName: ko.observable("Bert"),
lastName: ko.observable("Bertington"),
capitalizeLastName: function() {
var currentVal = this.lastName(); // Read the current value
this.lastName(currentVal.toUpperCase()); // Write back a modified value
}
};
the other way is to create a sort of constructor:
function viewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington"); etc.............
My instinct was to create my viewModels as function/classes but found that when defining functions inside for things like ajax calls etc, i was not able to update the viewModel variables inside the function definitions. I have to first define the viewModel and then "add" the functions after?
function LogOnModel() {
this.userName = ko.observable("");
this.password = ko.observable("");
this.userNameExists = ko.observable(true);
this.passwordCorrect = ko.observable(true);
this.returnURL = ko.observable(document.location.href.replace("http://" + location.host,""));
this.login = function () {
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(this),
dataType: 'json',
url: 'Account/LogOn',
success: function (result) {
this.userNameExists(result["UserNameExists"]);
this.passwordCorrect(result["PasswordCorrect"]);
alert(userLogOnModel.userNameExists);
}
});
this.loginFormFilled = ko.dependentObservable(function () {
if ((this.userName() != "") && (this.password() != ""))
return true;
else
return false;
}, this);
}
In the above the login function cannot update the userNameExists or passwordCorrect variables.. I tried a bunch of different syntax. When i move this function out of the constructor it works fine..
I just don't understand what would be the purpose of creating the sort of function constructor if none of the member function can exist inside it? What am i missing? thanks!
Upvotes: 9
Views: 3821
Reputation: 114792
Your issue is likely the value of this
in your callback. There are a couple of ways to make this work:
$.ajax accepts a context
parameter, so you could do add context: this
into your options that are passed to it.
You could also set this to a variable inside of this.login and use the variable in your result. It would be like:
this.login = function() {
var that = this;
....
success: function (result) {
that.userNameExists(result["UserNameExists"]);
that.passwordCorrect(result["PasswordCorrect"]);
}
}
Or you could bind your success function to this
, which will ensure that the function is called with the correct value for this
. It wpuld be like
success: function (result) {
this.userNameExists(result["UserNameExists"]);
this.passwordCorrect(result["PasswordCorrect"]);
alert(userLogOnModel.userNameExists);
}.bind(this)
Since, you are using $.ajax, the first option is the easiest.
Upvotes: 8