根据异步数据计算的计算可观察量

时间:2013-10-02 15:24:49

标签: javascript knockout.js knockout-2.0

在我的视图模型中,我有一个可观察的数组,需要从$ .getJSON调用填充。我想有一个计算的observable来表示返回的JSON中包含的“price”列的总和。

我设法填充了可观察数组...

(function($){

    function Coupon(expiration, value) {
        var self = this;
        self.expiration = expiration;
        self.value = value;
    }

    $(function() {
        $.when($.getJSON(coupons_url, null)).done(function(couponsJson) {
            ko.applyBindings({
                coupons: ko.utils.arrayMap(couponsJson[0].objects,
                    function(coupon) {
                        return new Coupon(coupon.expiration, coupon.value);
                    })

                savingsAvailable: ko.computed(function() {
                    var total = 0;
                    for (var i = 0; i < this.coupons().length; i++) {
                        total += parseFloat(this.coupons()[i].value / 100);
                    }
                    return total.toFixed(2);
                })
            });
        });

    });
})(jQuery);

...但是当我尝试填充计算的observable时,我不确定如何访问coupons的值。 this.coupons()出错:“this.coupons()不是函数”。我需要做些什么才能做到这一点,和/或我做错了什么?

1 个答案:

答案 0 :(得分:1)

ko.computed()接受第二个参数,该参数在计算计算的observable时定义“this”的值。那么什么对象持有“优惠券”你想要将其作为第二个参数传递。

或者您可以尝试以下内容创建视图模型,而不是动态定义对象并将其作为参数传递给applyBindings。

var Coupon = function(expiration, value) {
    var self = this;
    self.expiration = expiration;
    self.value = value;

}

var viewModel = function(couponsJson){

    var self = this;

    self.coupons = ko.utils.arrayMap(couponsJson[0].objects, function(coupon) {
        return new Coupon(coupon.expiration, coupon.value);
    })

    self.savingsAvailable = ko.computed(function() {
        var total = 0;
        for (var i = 0; i < self.coupons().length; i++) {
                total += parseFloat(self.coupons()[i].value / 100);
        }
        return total.toFixed(2);
    })                                              

}


(function($){
    $(function() {
        $.when($.getJSON(coupons_url, null)).done(function(couponsJson) {
            var vm = new viewModel(couponsJson)
            ko.applyBindings(viewModel);
        });

    });
})(jQuery);