如何在knockoutjs中结合限制和订阅?

时间:2012-08-27 17:30:30

标签: knockout.js

我有一个与服务器进行一些通信以报告当前屏幕几何等的功能

    function sendScreenLayout() { 
        logElementLocations(exp.getPageCoordinates());
    };

我将此函数订阅到我的代码中的某些事件,如下所示:

viewModel.onLayoutChange.subscribe(sendScreenLayout);
$('#right-splitter > #mainContent').resize(sendScreenLayout);
$(window).resize(sendScreenLayout);
...
setTimeout(sendScreenLayout, 1);

这些事件中的一些可能过于频繁地被发送以便由服务器有效地处理,并且我想将请求限制在一些合理的速率。

我能想到的最好的是这样的:

var triggerSend = ko.observable();

ko.computed(function() {
    triggerSend();
    logElementLocations(exp.getPageCoordinates());
}).extend({throttle: 200});

function sendScreenLayout() {
    triggerSend.valueHasMutated();
}

是否有更简洁的方法来捕捉这种模式,或者这是要走的路?

3 个答案:

答案 0 :(得分:10)

如果您使用Underscore,则可以使用debounce,如下所示:

var sendScreenLayout = _.debounce(function() { 
    logElementLocations(exp.getPageCoordinates());
}, 200);
...
$(window).resize(sendScreenLayout);
...

否则,它并不是Knockout直接支持的模式。你提出的解决方案似乎已经足够好了,尽管这是另一种选择:

var triggerSend = ko.computed({
    read: function() {},
    write: function(dummy) {
        logElementLocations(exp.getPageCoordinates());
    }
}).extend({throttle: 200});

function sendScreenLayout() {
    triggerSend(true);
}

答案 1 :(得分:4)

假设您的viewModel.onLayoutChange是可观察的,您只需执行以下操作:

ko.computed(function() {
    viewModel.onLayoutChange(); //implicitly subscribes this callback to changes
    logElementLocations(exp.getPageCoordinates());
}).extend({throttle: 200});

答案 2 :(得分:0)

上面的答案很优雅!我有一个必须排序的列表,顺序以及需要将其作为用户首选项保存到服务器的内容。我想在3个不同的属性更改上更新服务器,但不是每次更改都更新。做这样的事情。

ko.computed(function () {
    self.sort.direction();
    self.sort.order();
    self.sort.groupByPIC();

    if (!_firstLoad) {
        _dataService.updateSortPreferences({
            model : new _jsSortModel(self.sort)
        });
    }
}).extend({ throttle: 2000 });

允许我使用一个函数下标到多个属性,并在更新服务器之前为用户提供停止点击的时间。

非常好,谢谢!