javascript – ko.Computed()不使用observableArray更新

前端之家收集整理的这篇文章主要介绍了javascript – ko.Computed()不使用observableArray更新前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有如下代码
// First we define our gift class,which has 2 properties:
// a Title and a Price.
// We use knockout js validation to ensure that the values input are suitable/ 
function Gift(item)
{
    var self = this;
    self.Title = ko.observable(item.Title);

    // attach some validation to the Title property courtesy of knockout js validation
    self.Title.extend({
        required: true,minLength: 3,pattern: {
            message: 'At least ',params: '^[a-zA-Z]+\s?[a-zA-Z]*'
        }
    });
    self.Price = ko.observable(item.Price);
    self.Price.extend({required:true,number:true,min:0.1,max:1000});
};


var viewmodelForTemplated =
{
    gifts: ko.observableArray(),// gifts will be an array of Gift classes

    addGift: function ()
    {
        this.gifts.push(new Gift({ Title: "",Price: "" }));
    },removeGift: function (gift)
    {
        this.gifts.remove(gift);
    },totalCost: ko.computed(function () {
        if (typeof gifts == 'undefined')
            return 0;

        var total = 0;

        for (var i = 0; i < gifts().length; i++)
        {
            total += parseFloat(gifts()[i].Price());
        };
        return total;
    })
}


$(document).ready(function ()
{
    // load in the data from our MVC controller 
    $.getJSON("gift/getdata",function (allGifts)
    {
        var mappedgifts = $.map(allGifts,function (gift)
        {
            return new Gift(gift);
        });

        viewmodelForTemplated.gifts(mappedgifts);
    });

    ko.applyBindings(viewmodelForTemplated,$('#templated')[0]);
}

然后(脚本上面)

<div id="templated">

<table >
    <tbody data-bind="template: { name: 'giftRowTemplate',foreach: gifts }"></tbody>
</table>

<script type="text/html" id="giftRowTemplate">
    <tr>
        <td>Gift name: <input data-bind="value: Title"/></td>
        <td>Price: \$<input data-bind="value: Price"/></td>           
        <td><a href="#" data-bind="click: function() { viewmodelForTemplated.removeGift($data) }">Delete</a></td>
    </tr>
</script>

<p>Total Cost <span data-bind="text: totalCost"></span> </p>    

<button data-bind="click: addGift">Add Gift</button> 

<button data-bind="click: save">Save</button>

</div>

totalCost方法只运行一次,当礼物数组为空时,我可以将项目推送或删除到observableArray()中,但没有任何问题.

如何获取参考totalCost更新的跨度?我打赌这是一个简单的事情:)

谢谢你的帮助.

解决方法

你需要展开你的观察:
totalCost: ko.computed(function () {
    //also,you forgot typeof below
    if (typeof gifts == 'undefined')
       return 0;

    var total = 0;  //here \/
    for (var i=0; i < gifts().length; i++)
    {                //and here  \/
        total += parseFloat(gifts()[i].Price());
    };
    return total;
})

它不是更新的原因是因为

gifts.length

总是评估为0,永远不会进入循环.即使如此,

gifts[i].Price()

不会因为同样的原因而工作你需要展开可观察的.

请注意,当您不解开时,长度评估为零的原因是因为您获得了length of the actual observable array function. Knockout中的所有可观察值都被实现为常规函数;当你不打开它,你正在击中实际的功能本身,而不是底层的数组.

编辑,

此外,您需要使用此赠品参考礼品,因为它是一个对象属性.这就是为什么这不工作;礼物一直没有定义.

也就是说,你还需要做一些更多的工作来让ko计算机从一个对象字面上工作.在这里阅读更多信息:

http://dpruna.blogspot.com/2013/09/how-to-use-kocomputed-in-javascript.html

以下是我将如何使您的视图模型:

function Vm{
    this.gifts = ko.observableArray();        // gifts will be an array of Gift classes

    this.addGift = function () {
        this.gifts.push(new Gift({ Title: "",Price: "" }));
    };

    this.removeGift = function (gift)
    {
        this.gifts.remove(gift);
    };

    this.totalCost = ko.computed(function () {
        var total = 0;

        for (var i = 0; i < this.gifts().length; i++)
        {
            total += parseFloat(this.gifts()[i].Price());
        };
        return total;
    },this);
}

var viewmodelForTemplated = new Vm();

猜你在找的JavaScript相关文章