Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knockout pass additional parameters to subscription function

What I want to achieve is to create subscription for model properties. This subscription function should call WebApi via Ajax updating property value in database. For ajax call I need three paramaters: "fieldName", "fieldValue" and "modelId", ajax will update database row based on those three parameters.

I have many properties and all of them need the same functionality, so I do not want to subscribe for each property individually, so I found a following suggestion:

ko.subscribable.fn.withUpdater = function (handler) {
    var self = this;    
    this.subscribe(handler);    
    //support chaining 
    return this;    
};

Add this is how it is "attached" to observables:

self.ModelId= ko.observable();
self.CompanyName = ko.observable().withUpdater(update);

where update is some js function outside model.

However, I have problem, because I am not able to pass three paramaters to update functions (or also I can say in another words - I need to be able to get viewModel.ModelId property value inside update, as well as propertyName).

function update (propertyName, propertyNewValue, anotherPropertyValue) {
  //do ajax update 
}

As an example for CompanyName property it will be:

update("CompanyName", "New Company value here", 3), 

where

3 == viewModel.ModelId
like image 939
renathy Avatar asked Nov 26 '13 11:11

renathy


1 Answers

There might be a better way to do this, but the following will work:

First, add a target object to the withUpdate method:

ko.subscribable.fn.withUpdater = function (handler, target, propname) {
    var self = this;   

    var _oldValue;
    this.subscribe(function (oldValue) {
      _oldValue = oldValue;
    }, null, 'beforeChange');

   this.subscribe(function (newValue) {
     handler.call(target, _oldValue, newValue, propname);
   });

       return this;     
};

The update subscribe function will get scoped to the target property:

var update = function (propertyName) {
   console.log('propname is '+ propname + ' old val: ' + oldvalue + ', new val: ' +  newvalue + ', model id: ' + this.ModelId());
}

Now you will need to use it a little differently.

  self.CompanyName = ko.observable().withUpdater(update, self, "CompanyName");

An example http://plnkr.co/edit/HhbKEm?p=preview

I couldn't get the scope of the withUpdater function to be that of the object without explicitly passing in the target and a string for the company name.

like image 109
lucuma Avatar answered Sep 28 '22 07:09

lucuma