Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why in knockout.js examples is the viewmodel sometime defined as a function and other times a direct variable definition?

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!

like image 592
billy jean Avatar asked Jul 25 '11 23:07

billy jean


People also ask

What is Knockout ViewModel js?

A ViewModel can be any type of JavaScript variable. In Example 1-3, let's start with a simple JavaScript structure that contains a single property called name .

Which function used to perform computation in knockout JS?

Computed Observable is a function which is dependent on one or more Observables and automatically updates whenever its underlying Observables (dependencies) change.

How do you declare a ViewModel property as observable?

You just need to declare ViewModel property with function ko. observable() to make it Observable.

What is Ko observable in knockout JS?

Knockout. js defines an important role when we want to detect and respond to changes on one object, we uses the observable. An observable is useful in various scenarios where we are displaying or editing multiple values and require repeated sections of the UI to appear and disappear as items are inserted and deleted.


1 Answers

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.

like image 89
RP Niemeyer Avatar answered Nov 15 '22 16:11

RP Niemeyer