Javascript Knockout,从值中查找属性名称

时间:2013-04-24 03:17:26

标签: javascript knockout.js

我有两个按钮,按玩家名称和ID排序。 iam为每种类型使用两个函数,如。

<ul data-bind="template: { name: 'playerstmpl', foreach: players }"></ul>
<hr/>
<button data-bind="click: sortbyPlayer">Sort by Player</button>
<button data-bind="click: sortbyId">Sort by Id</button>
<script id="playerstmpl" type="text/html">
    <li> <span data-bind = "text: id"> </span>
        <input data-bind="value: FirstName" /> </li>
</script>



<script type="text/javascript">

    function Player(id, name) {
        return {
            id: ko.observable(id),
            FirstName: ko.observable(name)
            };
    }

    var viewModel = {
        players: ko.observableArray([
        new Player(64, "Yuvi"),
        new Player(22, "Gayle"),
        new Player(91, "Adam"),
        new Player(19, "Flintoff"),
        new Player(56, "Malinga")])
    };

    viewModel.sortbyPlayer = function () {
        var unsorted = viewModel.players();

        viewModel.players(unsorted.sort(viewModel.sortFunction = function (a, b) {

        return a.FirstName().toLowerCase() < b.FirstName().toLowerCase() ? -1 : 1;

        }));
    };


    viewModel.sortbyId = function () {
        var unsortedId = viewModel.players();

        viewModel.players(unsortedId.sort(viewModel.sortFunction = function (a, b) {
            return a.id() < b.id() ? -1 : 1;
        }));
    };
            ko.applyBindings(viewModel);

</script>

我试图找到函数中传递的属性,这样我就可以将两个函数合并为一个..比如

viewModel.sortbyPlayer = function () {
        var unsorted = viewModel.players();

        viewModel.players(unsorted.sort(viewModel.sortFunction = function (a, b) {

            if (Player[a] == "FirstName") {            // is string
                return a.FirstName().toLowerCase() < b.FirstName().toLowerCase() ? -1 : 1;
            }
       else {
            return a.id() < b.id() ? -1 : 1;
        }

        }));
    };

无论如何都要在一个函数中进行排序..谢谢

2 个答案:

答案 0 :(得分:1)

我会在sortByPlayersortById的视图模型上保留这两个属性,以便在您的ViewModel中清楚显示您正在公开的内容。接下来,我将创建一个函数来包装排序逻辑,但允许您传入一个参数,指示您要执行的排序类型(我称之为sortFunction)。然后,您的if语句按预期工作,如果您想要排序其他属性(如果/ Player对象发生更改),您甚至可以将其转换为switch语句:

function Player(id, name) {
    return {
        id: ko.observable(id),
        FirstName: ko.observable(name)
    };
}

var viewModel = {
    players: ko.observableArray([
            new Player(64, "Yuvi"),
            new Player(22, "Gayle"),
            new Player(91, "Adam"),
            new Player(19, "Flintoff"),
            new Player(56, "Malinga")
    ])
};

var sortFunction = function (sortBy) {
    return function () {
        var unsortedId = viewModel.players();
        viewModel.players(
            unsortedId.sort(function (a, b) {
                if (sortBy === 'player') {
                    return a.FirstName().toLowerCase() < b.FirstName().toLowerCase() ? -1 : 1;
                } else {
                    return a.id() < b.id() ? -1 : 1;
                }
            })
        );
    };
};

viewModel.sortbyPlayer = sortFunction('player');
viewModel.sortbyId = sortFunction('id');

ko.applyBindings(viewModel);

答案 1 :(得分:0)

如果您正在寻找更多通用排序功能.. 您可以检查属性type ..而不是name。这适用于您的情况,在更一般的情况下:

viewModel.sortbyPlayer = function () {
    var unsorted = viewModel.players();

    viewModel.players(unsorted.sort(viewModel.sortFunction = function (a, b) {
        if (typeof Player[a] === 'string') {            // is string
            return a.FirstName().toLowerCase() < b.FirstName().toLowerCase() ? -1 : 1;
        }
        if (typeofPlayer[a] === 'number') { 
            return a.id() < b.id() ? -1 : 1;
        }

    }));
};

您还可以使用魔法属性arguments来访问与函数一起使用的参数数组:

function someFunctionWithRandomParams(){
    if(arguments[0]){ 
        console.log('argument 1 of type'+ typeof arguments[0] +' and value'+arguments[0])
    }
    if(arguments[1]){ 
        console.log('argument 2 of type'+ typeof arguments[1] +' and value'+arguments[1])
    }
}