knockout将附加参数传递给订阅功能

ren*_*thy 7 javascript ajax jquery knockout.js

我想要实现的是为模型属性创建订阅.此订阅函数应通过Ajax更新数据库中的属性值来调用WebApi.对于ajax调用,我需要三个参数:" fieldName"," fieldValue"和" modelId",ajax将根据这三个参数更新数据库行.

我有很多属性,所有属性都需要相同的功能,所以我不想单独订阅每个属性,所以我找到了以下建议:

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

添加它是如何"附加"到observables:

self.ModelId= ko.observable();
self.CompanyName = ko.observable().withUpdater(update);
Run Code Online (Sandbox Code Playgroud)

这里update是模型之外的一些js函数.

但是,我有问题,因为我无法将三个参数传递给update函数(或者我可以用另一个词来说 - 我需要能够获得viewModel.ModelId内部的属性值update,以及propertyName).

function update (propertyName, propertyNewValue, anotherPropertyValue) {
  //do ajax update 
}
Run Code Online (Sandbox Code Playgroud)

作为CompanyName属性的示例,它将是:

update("CompanyName", "New Company value here", 3), 
Run Code Online (Sandbox Code Playgroud)

哪里

3 == viewModel.ModelId
Run Code Online (Sandbox Code Playgroud)

luc*_*uma 1

可能有更好的方法来做到这一点,但以下方法可行:

首先,向 withUpdate 方法添加一个目标对象:

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;     
};
Run Code Online (Sandbox Code Playgroud)

更新订阅函数的范围将限定为目标属性:

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

现在您需要以稍微不同的方式使用它。

  self.CompanyName = ko.observable().withUpdater(update, self, "CompanyName");
Run Code Online (Sandbox Code Playgroud)

一个例子 http://plnkr.co/edit/HhbKEm?p=preview

如果不显式传入目标和公司名称字符串,我无法将 withUpdater 函数的范围设置为对象的范围。