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

Computed observable calculated from async data

本文关键字:观察 计算 异步 数据      更新时间:2023-09-26

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

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

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

。但我不确定当我尝试填充计算的可观察量时如何访问coupons的值。 this.coupons()错误:"this.coupons() 不是一个函数"。我需要做什么才能完成此操作,和/或我做错了什么?

ko.computed() 在计算可观察量时,需要第二个参数来定义 "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);