Knockout observableArray项属性更改不会更新UI

时间:2013-08-13 23:35:38

标签: javascript knockout.js

当我将属性更改为observableArray时,它不会更新UI

请参阅下面的示例以及 jsFiddle

点击标题应更新sorting属性并显示/隐藏相应的span

使用Javascript:

var baseModel = [{
    key: 'name',
    type: 'string'
}, {
    key: 'surname',
    type: 'string'
}, {
    key: 'age',
    type: 'integer'
}]

var data = [{
    name: "John",
    surname: "Smith",
    age: 12
}, {
    name: "Peter",
    surname: "Klark",
    age: 3
}, {
    name: "Steve",
    surname: "Heisenberg",
    age: 43
}]

var vm = function () {
    var counter = 1;
    var people = ko.observableArray(data);
    var keys = ko.observableArray([]);
    var init = function () {
        var tempArray = [];
        _.each(baseModel, function (item, key) {
            tempArray.push({
                key: item.key,
                type: item.type,
                sorting: false,
                direction: "asc"
            });
        });
        // Set first column to sort by default
        tempArray[0].sorting = true;
        // Add 
        keys(tempArray);
    };

    var peopleList = ko.computed(function () {
        return people.sort(function (l, r) {
            var sortKey = _.where(keys(), {
                sorting: true
            }) || keys()[0];
            var result;
            if (typeof sortKey !== "undefined" && sortKey.length > 0) {
                result = (sortKey[0].direction === 'asc') ?
                    l[sortKey[0].key] > r[sortKey[0].key] ? 1 : -1 :
                l[sortKey[0].key] < r[sortKey[0].key] ? 1 : -1;
            } else {
                result = l[0] > r[0] ? 1 : -1;
            }
            return result;
        });
    });

    var addKey = function () {
        keys.push({
            key: "New Key No " + (counter++),
            type: 'string',
            sorting: false,
            direction: 'asc'
        });
    }

    var sortColumn = function (v) {
        if(v.sorting === true){
            v.direction = (v.direction === 'asc') ? 'desc' : 'asc';
        } else {
            _.each(keys(),function(item,key){
             keys()[key].sorting = false;
            })
            keys()[keys().indexOf(v)].sorting = true;
        }
        keys.valueHasMutated();
    }

    init();
    return {
        people: people,
        keys: keys,
        addKey: addKey,
        peopleList: peopleList,
        sort: sortColumn
    }
}

ko.applyBindings(new vm());

HTML:

<table>
    <thead>
        <tr data-bind="foreach: keys">
            <td data-bind="click: $root.sort">
                <span data-bind="text: $data.key"></span>
                <span data-bind="visible: $data.sorting, text: 'sorting'"></span>
            </td>
        </tr>
    </thead>
    <tbody data-bind="foreach: peopleList">
        <tr data-bind="foreach: $root.keys">
            <td data-bind="text: $parent[$data.key] || 'no data'">1</td>
        </tr>
    </tbody>
</table>
<button data-bind="click: addKey">Add new key</button>

1 个答案:

答案 0 :(得分:1)

您可以将排序属性变为可观察的:

tempArray.push({
    key: item.key,
    type: item.type,
    sorting: ko.observable(false),
    direction: "asc"
});

我根据你的小提琴进行了修改: http://jsfiddle.net/4LDZH/