6

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

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

有没有办法在可观察的属性更改后触发一次事件?

4

4 回答 4

26

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

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);

并且不要忘记在组件处置时处置订阅,以防它未被解雇。

于 2014-10-08T08:43:22.157 回答
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});
于 2012-12-04T11:26:37.017 回答
0

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

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

希望有人可以使用它。

于 2016-09-20T09:11:04.650 回答
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) {
    ...
});
于 2016-11-29T06:09:58.950 回答