如何创建只能触发一次的knockout observable订阅?

时间:2012-12-04 11:20:06

标签: javascript knockout.js

在我的模型中,我有一个异步加载的属性。我希望它在加载后生成另一个模型属性。

我正在考虑在第一个属性更改后可能触发的订阅,生成第二个属性然后被处置 - 我不知道如何从内部处理订阅。

有可能在可观察的属性更改后触发一次事件吗?

4 个答案:

答案 0 :(得分:24)

要从内部处理订阅,只需创建对它的引用:

var subscription = yourObservable.subscribe(function (newValue) {
    ...
    subsription.dispose();
});

如果您不想每次都编写此代码,可以使用新方法扩展observable:

ko.subscribable.fn.subscribeOnce = function (handler, owner, eventName) {
    var subscription = this.subscribe(function (newValue) {
        subscription.dispose();
        handler(newValue);
    }, owner, eventName);
    return subscription;
};

...

// usage
var subscription = yourObservable.subsribeOnce(yourHandler);

并且不要忘记在未被解雇的情况下处理组件处理的订阅。

答案 1 :(得分:0)

你可以写一个扩展器来压制除第一次射击之外的所有东西:

ko.extenders.fireOnce= function(target) {
    var fired=false;
    var result = ko.computed({
        read: target,
        write: function(newValue) {
            var current = target();
            if (newValue!== current && !fired) {
                fired=true;
                target(newValue);
            }
        }
    });
    result(target());
    return result;
};

然后按如下方式使用它:

var myObservable = ko.Observable(blah).extend({fireOnce:null});

答案 2 :(得分:0)

我们最终得到了这样的解决方案......

const subscription = observable.subscribe(() => {
  subscription.dispose();
  doStuff(settings);
});

希望有人可以使用它。

答案 3 :(得分:0)

详细说明@blazkovicz答案,subscribeOnce可以返回Promise最终以新值解析。打开有关如何公开subscription对象的建议; - )

ko.subscribable.fn.subscribeOnce = function (handler, owner, eventName) {
    var subscribable = this;
    var subscription;
    return new Promise(function(resolve) {
      subscription = subscribable.subscribe(resolve, owner, eventName);
    }).then(function(newValue) {
      subscription.dispose();
      handler && handler(newValue);
      return newValue;
    });
};

// usage
yourObservable.subscribeOnce().then(function(newValue) {
    ...
});