Knockout.JS中从数组中移除特定元素

44

我正在创建一款多人游戏,因此必须对网络事件做出反应。

我有这个简单的代码,但是removePlayer方法不起作用。addPlayer()很好用。

<table id="userlist2" class="tablesorter" cellspacing="0">
    <thead>
        <tr>
            <th>Name</th>
            <th>Queue</th>
            <th>Points</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: players">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: queue"></td>
            <td data-bind="text: score"></td>
        </tr>
    </tbody>
</table>


function PlayerViewModel() {
    var self = this;
    self.players = ko.observableArray();

    self.addPlayer = function (Name, QueuePos, Score) {
        self.players.push({
            name: Name,
            queue: QueuePos,
            score: Score
        });
    }


    self.removePlayer = function (Name) {
        for (var i = 0; i < self.players().length; i++) {

            if (self.players()[i].name == Name) console.log(i);
            self.players().splice(i, 1);
        }
    }
}


players = new PlayerViewModel();
ko.applyBindings(players);

players.addPlayer('Player1', '0', '0');
players.addPlayer('Player2', '0', '0');
players.removePlayer('Player2');

这是 http://jsfiddle.net/xseTc/


我更新了你的代码中的两行,请查看我的答案。 - ebram khalil
5个回答

80

您需要使用remove 函数

self.removePlayer = function (Name) {
    self.players.remove(function(player) {
        return player.name == Name;
    });
    
}

查看示例

HTML

<table id="userlist2" class="tablesorter" cellspacing="0">
    <thead>
        <tr>
            <th>Name</th>
            <th>Queue</th>
            <th>Points</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: players">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: queue"></td>
            <td data-bind="text: score"></td>
        </tr>
    </tbody>
</table>

JavaScript

function PlayerViewModel() {
    var self = this;
    
    self.players = ko.observableArray();  

    self.addPlayer = function (Name, QueuePos, Score) {
        self.players.push({
            name: Name,
            queue: QueuePos,
            score: Score
        });
    }

    self.removePlayer = function (Name) {
        self.players.remove(function(player) {
            return player.name == Name;
        });
    }
}

players = new PlayerViewModel();
ko.applyBindings(players);

players.addPlayer('Player1', '0', '0');
players.addPlayer('Player2', '0', '0');
players.removePlayer('Player2');

1
玩家的名字不是 player.name() == Name 吗? - Karussell
1
@karussel:只是因为没有人回答这个评论:这是一个“精简”的结构,单个玩家属性不可观测。 - deblocker

12

删除功能的工作方式:

self.removePlayer = function (name) {
    self.players.remove(function(player) { 
        return player.name == name
    });
}

3

你的代码很好,除了两个错误:

if (self.players()[i].name == Name) console.log(i);
    self.players().splice(i, 1);

首先,你正在执行两行代码,因此为了同时执行它们,你需要使用 {} 代替:

if (self.players()[i].name == Name) {
    console.log(i);
    self.players.splice(i, 1);
}

使用splice方法时,无需在调用可观察的数组时加上(),因此您可以按照以下方式使用它:

self.players.splice(i, 1);

Working Demo


0
如果你像这样将视图模型添加到玩家数组中:
self.addPlayer = function (Name, QueuePos, Score) {
    self.players.push(new PlayerVM(Name, QueuePos, Score)));
}

然后你可以像这样移除玩家对象:

self.removePlayer = function (player) {
    self.players.remove(player);
}

或者从播放器虚拟机内部:

parentVM.players.remove(self);

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接