Javascript 使用嵌套循环更新ViewModel淘汰

Javascript 使用嵌套循环更新ViewModel淘汰,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,这可能不是完成任务的完全理想的优化方式。我愿意接受任何更好的建议。到目前为止,负载工作性能良好 我有我的击倒应用程序通过ajax加载工作。在绑定调用中,我有一个嵌套循环,其中包含一个函数,该函数根据设置值更新点 当我尝试添加一个新项目时,不会抛出任何错误,但是UI不会更新,我似乎不知道为什么 这是我想做的一堆事情。 addCombatant方法确实有效,但无论出于何种原因,该表都不会重新绑定。您可以在输出到控制台的VM json中看到附加值 self.addCombatant = functi

这可能不是完成任务的完全理想的优化方式。我愿意接受任何更好的建议。到目前为止,负载工作性能良好

我有我的击倒应用程序通过ajax加载工作。在绑定调用中,我有一个嵌套循环,其中包含一个函数,该函数根据设置值更新点

当我尝试添加一个新项目时,不会抛出任何错误,但是UI不会更新,我似乎不知道为什么

这是我想做的一堆事情。

addCombatant方法确实有效,但无论出于何种原因,该表都不会重新绑定。您可以在输出到控制台的VM json中看到附加值

self.addCombatant = function(combatant){
        ko.utils.arrayForEach(self.divisions(), function(d){
            if(d.name() == combatant.division){
                d.combatants().push({name: combatant.name,
                            ID: combatant.ID,
                            swords:{points: 0, time:'none', kills: 0}
                            });
            }
       console.log(ko.toJSON(self.divisions));
    }
)}.bind(this);
编辑:


我已经应用了下面建议的一些更新,并添加了另一个要排序的列表。它绑定并更新,但是,当我添加一个战斗人员时,它只绑定到一个事件,并且排序被关闭。如果我不能使用sortDivision(战士,剑),我该如何进行自动排序?在这个fiddle()中,我希望事件按kills排序,然后按时间排序。是否可以在客户端完成此多级排序而不创建另一个observeLearRay?

您正在推进底层数组,从而绕过更改跟踪。删除括号(d.push)或在完成后调用valueHasMutated

您需要:

    if(d.name() == combatant.division){
        d.combatants.push({name: combatant.name,
                    ID: combatant.ID,
                    swords:{points: 0, time:'none', kills: 0}
                    });
    }
或:


您正在进入底层数组,因此绕过了更改跟踪。删除括号(d.push)或在完成后调用valueHasMutated

您需要:

    if(d.name() == combatant.division){
        d.combatants.push({name: combatant.name,
                    ID: combatant.ID,
                    swords:{points: 0, time:'none', kills: 0}
                    });
    }
或:


这是表中的foreach绑定

    <!-- ko foreach: $root.sortDivision(combatants, 'swords') -->
您的
sortBy
函数将创建一个新的
observableArlay
。这与推送到的
observearray
不同

ko.observableArray.fn.sortBy = function (evt, fld, direction) {
    var isdesc = direction && direction.toLowerCase() == 'desc';
    return ko.observableArray(this.sort(function (a, b) {
        a = ko.unwrap(evt ? a[evt][fld]() : a[fld]());
        b = ko.unwrap(evt ? b[evt][fld]() : b[fld]());
        return (a == b ? 0 : a < b ? -1 : 1) * (isdesc ? -1 : 1);
    }));
};
ko.observearray.fn.sortBy=功能(evt、fld、方向){
var isdesc=direction&&direction.toLowerCase();
返回ko.observearray(this.sort)(函数(a,b){
a=ko.unwrap(evt?a[evt][fld]():a[fld]());
b=ko.unwrap(evt?b[evt][fld]():b[fld]());
返回(a==b?0:a

您应该使用
computed
s(或
pureComputed
s)来表示数据的重新表示或重新组合。将任何数据项存储在一个位置。

这是表中的foreach绑定

    <!-- ko foreach: $root.sortDivision(combatants, 'swords') -->
您的
sortBy
函数将创建一个新的
observableArlay
。这与推送到的
observearray
不同

ko.observableArray.fn.sortBy = function (evt, fld, direction) {
    var isdesc = direction && direction.toLowerCase() == 'desc';
    return ko.observableArray(this.sort(function (a, b) {
        a = ko.unwrap(evt ? a[evt][fld]() : a[fld]());
        b = ko.unwrap(evt ? b[evt][fld]() : b[fld]());
        return (a == b ? 0 : a < b ? -1 : 1) * (isdesc ? -1 : 1);
    }));
};
ko.observearray.fn.sortBy=功能(evt、fld、方向){
var isdesc=direction&&direction.toLowerCase();
返回ko.observearray(this.sort)(函数(a,b){
a=ko.unwrap(evt?a[evt][fld]():a[fld]());
b=ko.unwrap(evt?b[evt][fld]():b[fld]());
返回(a==b?0:a


您应该使用
computed
s(或
pureComputed
s)来表示数据的重新表示或重新组合。将任何数据项存储在一个位置。

您知道Knockout有一个单击绑定,对吗?此外,排序函数中出现了一些错误。这是有效的:是关于单击绑定。但这不是重点。我正在尝试隔离更新问题。我的实际应用程序还有很多。德克,我知道你用嵌套循环做了什么。我尝试使用其他语言的技术的另一个例子。你知道Knockout有一个点击绑定,对吗?另外,排序函数出现了一些问题。这是有效的:是关于单击绑定。但这不是重点。我正在尝试隔离更新问题。我的实际应用程序还有很多。德克,我知道你用嵌套循环做了什么。另一个例子是我尝试使用其他语言的技术。我尝试使用计算机,但它根本不起作用。我不是说我不会再回去了。@Roy,我比你投了更高的票,因为这是他第二个问题的正确方法。我试着用一个计算机,但根本不起作用。但我并没有说我不会再回去了。@Roy,我给你投了高票,因为这是他第二个问题的正确方法。valueHasMutated似乎没有任何作用。我编辑了我的答案,以便更具体一些。你试过以上两种方法了吗?两种方法都不行,因为战斗人员不是被列出的阵型。事实上,看看第一和第二小提琴之间的区别,你确实按照我的建议删除了d.combatant中的括号。这就是为什么当你在fiddle 2中添加一名战士时,显示会更新。然后,您添加了关于排序的第二个问题。我回答了你的第一个问题。如果在我的回答帮助您之后,您需要对新发现的行为提供额外的帮助,您应该将我的回答标记为正确并打开一个新问题。我的编辑尝试了这两种方法,但都没有起到任何作用。仍然需要对绑定上的分区进行排序。如果您更改了某些数据,我的旧方法将保持排序。是的,将()添加到列表中并使用valueHasMutated()确实有效。这是你的答案和德克的评论的结合。valueHasMutated似乎没有任何作用。我编辑了我的答案,以使其更具体。你试过以上两种方法了吗?两种方法都不行,因为战斗人员不是被列出的阵型。事实上,看看第一和第二小提琴之间的区别,你确实按照我的建议删除了d.combatant中的括号。这就是为什么当你在fiddle 2中添加一名战士时,显示会更新。然后,您添加了关于排序的第二个问题。我回答了你的第一个问题。如果在我的回答帮助您之后,您需要对新发现的行为提供额外的帮助,您应该将我的回答标记为正确并打开一个新问题。我的编辑尝试了这两种方法,但都没有起到任何作用。仍然需要对绑定上的分区进行排序。我的老办法是,如果你