Knockoutjs。 如何计算可观测阵列内改变的数据(Knockoutjs. How to c

2019-08-01 02:06发布

请看看我的文字。 我尝试用knockoutjs的observableArray和foreach来计算阵列的数据。 例1正常工作:如果您更改字段中的数据总和计算。 但是例2不工作。

<html>
<head>                                                                         
    <title></title>                                                            
    <script type='text/javascript' src='/js/jquery-1.8.2.min.js'></script>     
    <script type='text/javascript' src='/js/knockout-2.1.0.debug.js'></script> 
</head>                                                                        
<body>
<p>Example 1</p>
<div>
    <p>
    <input data-bind="value: fnum1" />
    <input data-bind="value: fnum2" />
    <span data-bind="text: ftotsum"></span>
    </p>
</div>    
<p>Example 2</p>
<div>
    <p>
    <!-- ko foreach: fields -->
    <input data-bind="value: $data" />
    <!-- /ko -->
    <span data-bind="text: ltotsum"></span>
    </p>
</div>
</body>
<script>
    function vm(){
        //Calc Example 1
        var self = this;
        self.fnum1 = ko.observable(1);
        self.fnum2 = ko.observable(2);
        self.ftotsum = ko.computed(function(){
            return parseFloat(self.fnum1()) + parseFloat(self.fnum2());
        });
        //Calc Example 2
        self.fields = ko.observableArray([1, 2]);
        self.ltotsum = ko.computed(function(){
            var total = 0;
            ko.utils.arrayForEach(self.fields(), function(item) {
                total += parseFloat(item);
            })
            return total;
        }); 
    };

    ko.applyBindings(new vm());
</script>
</html>

Answer 1:

编辑:得到拨弄工作,拉斐尔是说你需要用可观察的对象内是正确的,但你可以在阵列创作本身内做到这一点,我喜欢用ko.utils解开我的观测,它做同样的事情对观测但是如果有一个不可观察的传递给它,它不会崩溃。 见拨弄了完整的例子。

一个observableArray不会使值通过观察到的,这是一个常见的错误。 一个observableArray只是观察修改阵列而不是值。 如果您希望您的阵列内你的价值观是可观察的,你必须让他们如此。

function vm(){
    //Calc Example 1
    var self = this;
    self.fnum1 = ko.observable(1);
    self.fnum2 = ko.observable(2);
    self.ftotsum = ko.computed(function(){
        return parseFloat(self.fnum1()) + parseFloat(self.fnum2());
    });
    //Calc Example 2
    self.fields = ko.observableArray([{"num":ko.observable(1)},{"num":ko.observable(2)}]);
    self.ltotsum = ko.computed(function(){
        var total = 0;
        ko.utils.arrayForEach(self.fields(), function(item) {
            total += parseFloat(ko.utils.unwrapObservable(item.num));
        });
        return total;
    }); 
};
ko.applyBindings(new vm());

应与工作例如上面了。



Answer 2:

该文件说:

关键点:一个observableArray轨道哪些对象是在阵列中,而不是那些对象的状态

简单地把对象装进observableArray不作眼前一亮观察到该对象的属性。 当然,你可以让这些属性可观察到的,如果你愿意的话,但是这是一个独立的选择。 一个observableArray只跟踪哪些对象它保持,并且当对象被添加删除通知侦听。

您的第二示例不起作用,因为输入字段的值被未绑定到数组中的值。 数组中的值只使用一次,在foreach约束力的,但是当你在输入框中键入,没有触发KO。

这是一个工作小提琴与实施的解决方案。 我用了一个帮手ObsNumber

function vm(){
    var self = this;

    var ObsNumber = function(i) {
        this.value = ko.observable(i);
    }

    self.fields = ko.observableArray([new ObsNumber(1) ,
                                      new ObsNumber(2)]);

    self.sum = ko.computed(function(){
        var total = 0;
        ko.utils.arrayForEach(self.fields(), function(item) {
            total += parseFloat(item.value());
        });
        return total;
    });
};

ko.applyBindings(new vm());

而下面的标记

<div>
    <p>
    <!-- ko foreach: fields -->
    <input data-bind="value: $data.value" />
    <!-- /ko -->
    <span data-bind="text: sum"></span>
    </p>
</div>​


文章来源: Knockoutjs. How to compute data changed inside observable array