未跟踪可观察数组中的KnockoutJS可观察属性

时间:2015-09-04 12:44:38

标签: knockout.js

这是一个模型:

        function DiscountItem(minDays, percent) {
            var self = this;
            self.minDays = ko.observable(minDays);
            self.discount = ko.observable(percent);
        }

        function TableItem(name, from, to, price, hasDiscount) {
            var self = this;
            self.name = name;
            self.from = from;
            self.to = to;
            self.price = price;
            self.discount = hasDiscount;
        }

        function AppViewModel() {
            var self = this;

            self.discounts = ko.observableArray([
                new DiscountItem(12, 4),
                new DiscountItem(20, 6)
            ]);

            self.table = ko.observableArray([
                new TableItem("first", "20.03","3.04", 400, 1),
                new TableItem("second", "11.04","4.05", 600, 0)
            ]);

            self.addDiscount = function() {
                self.discounts.push(new DiscountItem(0, 0));
            }

            self.removeDiscount = function() {
                self.discounts.remove(this);
            }

            self.addPeriod = function() {
                self.table.push(new TableItem("","","", 0, 1));
            }

            self.removePeriod = function() {
                self.table.remove(this);
            }

            self.pricing = ko.computed(function() {
                return JSON.stringify({
                    durationDiscount : self.discounts(),
                    periods: self.table()
                })
            }, self);
        }

这就是我需要的: enter image description here

每当我更改observable属性中的一个或在observableArray中添加新项时,我需要使用从self.discounts和self.table组合的数据的JSON表示来填充其他输入

类似这样的事情

{"durationDiscount":[{"minDays":12,"discount":4},{"minDays":20,"discount":6}],"periods":[{"name":"first","from":"20.03","to":"3.04","price":400,"discount":1},{"name":"second","from":"11.04","to":"4.05","price":600,"discount":0}]}

如果我在模型属性上删除ko.observable(),那么一切正常,但我需要跟踪它们。

如果我添加ko.observable(),ko.computed中的self.discounts会将我的空数组回归

2 个答案:

答案 0 :(得分:1)

我认为唯一的问题是,当这些属性可观察时,您的pricing属性中没有获得。试试这个:

self.pricing = ko.computed(function() {
    return JSON.stringify({
        durationDiscount : self.discounts().map(function(x){ 
              return { minDays: x.minDays(), discount: x.discount() }
        }),
        periods: self.table()
    })
}, self);

function DiscountItem(minDays, percent) {
    var self = this;
    self.minDays = ko.observable(minDays);
    self.discount = ko.observable(percent);
}

function TableItem(name, from, to, price, hasDiscount) {
    var self = this;
    self.name = name;
    self.from = from;
    self.to = to;
    self.price = price;
    self.discount = hasDiscount;
}

function AppViewModel() {
    var self = this;

    self.discounts = ko.observableArray([
        new DiscountItem(12, 4),
        new DiscountItem(20, 6)
    ]);

    self.table = ko.observableArray([
        new TableItem("first", "20.03","3.04", 400, 1),
        new TableItem("second", "11.04","4.05", 600, 0)
    ]);

    self.addDiscount = function() {
        self.discounts.push(new DiscountItem(0, 0));
    }

    self.removeDiscount = function() {
        self.discounts.remove(this);
    }

    self.addPeriod = function() {
        self.table.push(new TableItem("","","", 0, 1));
    }

    self.removePeriod = function() {
        self.table.remove(this);
    }

    self.pricing = ko.computed(function() {
        return JSON.stringify({
            durationDiscount : self.discounts().map(function(x){ return { minDays: x.minDays(), discount: x.discount() }}),
            periods: self.table()
        })
    }, self);
}

ko.applyBindings(new AppViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="foreach: discounts">
    <div>
        <span><input data-bind="value: minDays" /></span>
        <span><input data-bind="value: discount" /></span>
    </div>
</div>

<pre data-bind="text: pricing"></pre>

答案 1 :(得分:1)

observableArray实际上并未提供有关项目更改的通知,请参阅documentation note。因此,您有两种选择 - 订阅项目的更改或在您计算的范围内调用项目的可观察性。我喜欢这样的第二个

self.pricing = ko.computed(function() {
         return ko.toJSON({
                durationDiscount : ko.utils.arrayMap(this.discounts(), 
function(item){ 
  return new DiscountItem(ko.unwrap(item.discount), ko.unwrap(item.minDays)); })
               })}, self);

查看我的前叉http://jsfiddle.net/xv62vs6c