使用progressbar和knockout处理可观察的viewmodel数组

时间:2014-01-27 19:57:21

标签: knockout.js

我试图找出如何做这样的事情,比如自动处理服务器上某些视图模型的可观察数组,并让它逐个更新jquery ui progressbar,我想出了以下代码:)

<div data-bind="progressBar: { value: progressValue, max: ViewModels().length }" style="width: 100%">
</div>

ko.bindingHandlers.progressBar = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var value = valueAccessor();
            $(element).progressbar({
                    value: false,
                    max: ko.unwrap(value.max)
                });
        },
        update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var value = valueAccessor();
            $(element).progressbar("option", "value", ko.unwrap(value.value));
        }
    }

function ViewModel(model) {
        var self = this;
        ko.mapping.fromJS(JSON.parse(model), {}, self);

        self.progressValue = ko.observable(0);
        ko.computed(function () {
            if (self.ViewModels().length > 0) {
                var first = self.ViewModels()[0];
                $.ajax({
                    //send first viewmodel on server and do something with it
                    success: function (result) {
                        self.ViewModels.remove(first);
                        self.progressValue(self.progressValue() + 1);
                    }
                });
            }
        })
    }

当计算递归调用时,您如何看待这种方法?也许你没有看到任何真正的用法,但如果,你会怎么做呢?

1 个答案:

答案 0 :(得分:1)

文档说:

  

Knockout在评估

时不会重新开始计算的评估

(read more here)

所以,如果它真的是递归的,你的方法就会出问题。

但是在你的情况下它并不是真正的递归,因为只有当服务器在一个单独的执行堆栈中响应(它是异步)时才会调用success回调。

所以我认为你的方法很好,假设它为你提供了你正在寻找的功能。

一个没有计算的简单方法就是把它放在一个函数中并从成功回调中调用函数:

        self.progressValue = ko.observable(0);

        sendRemaining();

        function sendRemaining() {    
            if (self.ViewModels().length > 0) {
                var first = self.ViewModels()[0];
                $.ajax({
                    //send first viewmodel on server and do something with it
                    success: function (result) {
                        self.ViewModels.remove(first);
                        self.progressValue(self.progressValue() + 1);
                        sendRemaining();
                    }
                });
            }
        }