KnockoutJS订阅具有相同回调操作的多个observable

时间:2012-02-14 14:21:13

标签: javascript knockout.js

我在KnockoutJS中有一个模型类,它有多个我想订阅的值。每个订阅都将执行相同的任务,如下所示:

function CaseAssignmentZipCode(zipCode, userId, isNew) {
  var self = this;
  self.zipCode = ko.observable(zipCode);
  self.userId = ko.observable(userId);
  self.isNew = isNew;
  self.isUpdated = false;

  self.zipCode.subscribe(function () { self.isUpdated = true; });
  self.userId.subscribe(function () { self.isUpdated = true; });
}

有没有办法将这两个调用合并为subscribe,这样我就可以使用一个订阅来“监视”这两个值?

5 个答案:

答案 0 :(得分:26)

您可以为此目的使用计算的observable。您只需要确保在read函数中访问每个observable的值。会是这样的:

ko.computed(function() {
   self.zipCode();
   self.userId();
   self.isUpdated = true;
});

所以,你依赖于两个observable并设置你的旗帜。

此外,如果您正在寻找类似“脏”标志的东西,那么您可能会考虑类似:http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html。这个想法是你使用一个在对象上调用ko.toJS()的计算observable来解包它的所有可观察对象。

答案 1 :(得分:17)

你不想复制处理函数的主体吗?将其解压缩为变量。

function CaseAssignmentZipCode(zipCode, userId, isNew) {
  var self = this;
  self.zipCode = ko.observable(zipCode);
  self.userId = ko.observable(userId);
  self.isNew = isNew;
  self.isUpdated = false;

  var handler = function () { self.isUpdated = true; };

  self.zipCode.subscribe(handler);
  self.userId.subscribe(handler);
}

答案 2 :(得分:2)

通过将依赖项列表转换为循环来改进将函数体重构为变量:

function CaseAssignmentZipCode(zipCode, userId, isNew) {
  var self = this;
  self.zipCode = ko.observable(zipCode);
  self.userId = ko.observable(userId);
  self.isNew = isNew;
  self.isUpdated = false;

  var handler = function () { self.isUpdated = true; };

  ko.utils.arrayForEach([self.zipCode, self.userId], function(obs) {
    obs.subscribe(handler);
  });
 } 

答案 3 :(得分:2)

您可以为此目的创建某种扩展名。简单的例子:

function subscribeMany(callback, observables) {    
    for (var i = 0; i < observables.length; i++) {
        observables[i].subscribe(callback);
    }
}

用法:

var name = ko.observable();
var email = ko.observable();

var callback = function(value) {
    console.log(value);
};

subscribeMany(callback, [name, email]);

name('test 1')
email('test 2')

答案 4 :(得分:0)

用于在Observable列表中的任何Observable上执行相同回调的Typescript版本。

此解决方案适用于以下类型:

  1. KnockoutObservableArray<KnockoutObservable<T>>
  2. KnockoutObservable<KnockoutObservable<T>[]>
  3. KnockoutObservable<T>[]
  4. 这种方法的好处:

    1. 如果Observable被添加到您的KnockoutObservableArray,则会检测到更改,并且订阅功能也将添加到该Observable中。
    2. 同一解决方案可用于多种不同类型,并为您处理类型。

      function subscribeMany<T>(
          observables: KnockoutObservableArray<KnockoutObservable<T>> | KnockoutObservable<KnockoutObservable<T>[]> | KnockoutObservable<T>[],
          callback: (v: T) => void
          ): KnockoutObservableArray<KnockoutObservable<T>> | KnockoutObservable<KnockoutObservable<T>[]> | KnockoutObservable<T>[] {
      
          function _subscribeMany<T>(
              observables: KnockoutObservableArray<KnockoutObservable<T>> | KnockoutObservable<KnockoutObservable<T>[]> | KnockoutObservable<T>[],
              callback: (v: T) => void): void {
      
              if (_isObservableArray<T>(observables)) {
                  _subcribeAndRun(observables, (array) => {
                      array.forEach((observable) => {
                          observable.subscribe(callback);
                      });
                  });
              }
              else {
                  observables.forEach((observable) => {
                      observable.subscribe(callback);
                  });
              }
          }
      
          function _isObservableArray<T>(observables: KnockoutObservableArray<KnockoutObservable<T>> | KnockoutObservable<KnockoutObservable<T>[]> | KnockoutObservable<T>[]): observables is KnockoutObservableArray<KnockoutObservable<T>> | KnockoutObservable<KnockoutObservable<T>[]> {
              return "subscribe" in observables;
          }
      
          function _subcribeAndRun<T>(o: KnockoutObservable<T>, callback: (v: T) => void): KnockoutObservable<T> {
              o.subscribe(callback);
              callback(o());
      
              return o;
          }
      
          _subscribeMany<T>(observables, callback);
          return observables;
      }