Dania_es
Dania_es

Reputation: 1036

Get viewmodel context in click binding function in durandal viewmodel

I'm trying to access an observable from a click function, but can't figure out the right context.

define(['plugins/http', 'durandal/app', 'knockout', 'session'], function (http, app, ko, session) {
  return {
    contacts: ko.observableArray([]),
        activate: function () {

            var that = this;
            headers = {contentType: "application/json", token: session.token}
            return http.get('/api/contacts', {}, headers).then(function(response) {
                that.contacts(response);
            });
    },
    Delete: function(contact) {
            console.log(this.contacts);
            //this.contacts.remove(contact);
    },
  };
});

this.contacts is undefined, as is any combination of $root, $parent, etc. How can I get the right context to use the observable? (Delete(contact) is bound with click: in the view.)

Upvotes: 0

Views: 598

Answers (2)

Peter Wone
Peter Wone

Reputation: 18765

There's nothing wrong with Luis answer but I do it differently and it won't hurt you to see other options.

define(['plugins/http', 'durandal/app', 'knockout', 'session'], 
    function (http, app, ko, session) {

  var vm = {
    contacts:  ko.observableArray([])
  };

  vm.activate = function () {
    headers = { contentType: "application/json", token: session.token }
    return http.get('/api/contacts', { }, headers)
      .then(function(response) { vm.contacts(response); });
  };

  vm.Delete = function(contact) {
    console.log(vm.contacts());
  };

  return vm;

});

I favour this way because it's a lot easier to see what's going on, but it's only suitable for singleton scenarios.

Upvotes: 2

Luis
Luis

Reputation: 6001

Try this:

define(['plugins/http', 'durandal/app', 'knockout', 'session'], 
    function (http, app, ko, session) {

    function myVm(){
        var self=this;
        self.contacts =  ko.observableArray([]);
        self.activate =  function () {

            var that = this;
            headers = {contentType: "application/json", token: session.token}
            return http.get('/api/contacts', {}, headers).then(function(response) {
            that.contacts(response);
            });
        }
        self.Delete = function(contact){
            console.log(self.contacts());
        }
    }

    return new myVm();
  };
});

What we doing here is creating a self variable in the function scope, that will allow you to reference the actual object inside closures where this does not refer to the object anymore.

Warning did not test the code so there might be errors

Upvotes: 2

Related Questions