使用Knockout.js中的新项更新可观察数组的位置

时间:2014-04-17 06:32:44

标签: javascript arrays knockout.js

我有一种情况需要在可观察数组中的某个位置替换某个项目。现在我用切片方法在下面做。是否有一种更好的方法可以将knockout.js内置于特定位置?我甚至考虑进行推送,然后使用订单属性对该行进行排序,但我有很多行并认为这很多。

var position = ko.utils.arrayIndexOf(self.list(), game);

if (position != -1) {
   self.list.remove(self.game);
   self.list.splice(position, 0, newGame);
}

替换代码,尝试更新具有名称新属性的属性匹配

var game = self.game;

                    if (game) {

                        var position = ko.utils.arrayIndexOf(self.list(), game);

                        if (position != -1) {

                            if (game.Matchup) {
                                game.Matchup = new Matchup(response.Data);
                                game.Modified(true);
                            }
                            else if (self.game) {
                                game = new Matchup(response.Data);
                            }

                            self.list.replace(self.list()[position], game);
                        }
                    }

HTML

                <!-- ko foreach: Games -->
                <td class="item-container draggable-item-container clearfix">
                    <div class="item clearfix draggable-active draggable-item" data-bind="draggableCss: { disabled: $data.Disabled(), matchup: $data.Matchup }, draggableGameHandler : { disabled: !$data.Matchup, disabledDrop: $data.Disabled() }, delegatedClick: $root.members.eventSchedule.editGame.open.bind($data, true, ($data.Matchup && $data.Matchup.Type == '@((int)ScheduleType.Pool)'), $parent.Games)">
                        <span data-bind="if: $data.Matchup">
                            <span data-bind="attr: { title: Matchup.Title }"><span data-bind="html: Matchup.Name"></span></span>
                        </span>
                    </div>
                </td>
                <!-- /ko -->

data-bind="html: Matchup.Name"无法使用替换进行更新。

2 个答案:

答案 0 :(得分:2)

替换可观察数组中的项

replace方法是替换可观察数组中的项的一个选项。在你的情况下,你可以这样称呼它:

list.replace(game, newGame);

当可观察的依赖项更改时,绑定会更新

但您的问题不仅仅是更换数组中的项目。您已声明绑定html: Matchup.Name未更新,因此请查看可能导致其更新的内容:

  1. 如果Name是可观察的,则修改Name会导致更新。
  2. 如果Matchup是可观察的,修改它会导致更新,但是您必须像Matchup().Name那样绑定它,并像game.Matchup(Matchup(response.Data));一样更新它。
  3. 使用新对象替换可观察数组中的条目(是Games还是list?)会导致整个内部模板重新呈现,显然会替换每个绑定。
  4. 通过查看代码,我可以看到在一种情况下(if (game.Matchup)),这三件事都不会发生,因此Knockout无法知道更新绑定。前两个显然没有发生,虽然你在数组上调用replace,但它相当于:

    list.replace(game, game);   // replace the item with itself
    

    foreach绑定不会将上述内容视为更改,并且不会更新任何内容。因此,要更新绑定,您需要对可观察的内容进行真正的更新。

    进一步评论

    要获取可观察数组中项的索引,请使用indexOf方法:

    var position = self.list.indexOf(game);
    

    要替换特定索引处的项目,请使用splice方法和第二个参数1

    self.list.splice(position, 1 /*how many to remove*/, newGame);
    

答案 1 :(得分:1)

Observable arrays有一个内置的.replace方法可用于执行此操作:

var position = ko.utils.arrayIndexOf(self.list(), game);

self.list.replace(self.list()[position], game);