Javascript 在嵌套的ObservalArray中按一个关键字筛选用户

Javascript 在嵌套的ObservalArray中按一个关键字筛选用户,javascript,stack-overflow,observablecollection,knockout.js,Javascript,Stack Overflow,Observablecollection,Knockout.js,我正在尝试筛选我的用户observableArray,其中包含嵌套关键字observableArray 基于我的viewModel上的一个可观察的关键字阵列 当我尝试使用ko.utils.arrayForEach时,我得到一个堆栈溢出异常。参见下面的代码,也发布在 函数用户(id、名称、关键字){ 返回{ id:ko.可观察(id), 名称:ko.可观察(名称), 关键词:ko.observableArray(关键词), isVisible:ko.dependentObservable(函数()

我正在尝试筛选我的
用户
observableArray,其中包含嵌套关键字observableArray
基于我的viewModel上的一个可观察的关键字阵列

当我尝试使用
ko.utils.arrayForEach
时,我得到一个堆栈溢出异常。参见下面的代码,也发布在

函数用户(id、名称、关键字){
返回{
id:ko.可观察(id),
名称:ko.可观察(名称),
关键词:ko.observableArray(关键词),
isVisible:ko.dependentObservable(函数(){
可见值=假;
if(viewModel.selectedKeyword()| | viewModel.KeywordsDirty()){
ko.utils.arrayForEach(关键字,函数(关键字){
如果(关键字===viewModel.selectedKeyword()){
可见=真实;
}
});
如果(!可见){
viewModel.users.remove(此);
}
}
返回可见;
})
}
};
函数关键字(计数、字){
返回{
计数:可观察到的ko(计数),
单词:ko.可观察(单词)
}
};
var viewModel={
用户:ko.observearray([]),
关键词:ko.observableArray([]),
selectedKeyword:ko.observable(),
关键词Dirty:ko.可观察(假)
}
viewModel.selectedKeyword.subscribe(函数(){
如果(!viewModel.keywordIsDirty()){
viewModel.keywordIsDirty(true);
}
});
应用绑定(视图模型);
对于(变量i=0;i<500;i++){
viewModel.users.push(
新用户(i,“男士”+i、[“啤酒”、“女士”、“食品”])
)
}
viewModel.keywords.push(新关键字(1,“啤酒”);
viewModel.keywords.push(新关键字(2,“女性”);
viewModel.keywords.push(新关键字(3,“食物”);
viewModel.keywords.push(新关键字(4,“烹饪”);
以及查看代码:


    • ${word}
    • ${$data.name}

    • 您的
      isVisible
      DependentToServable已经创建了对自身的依赖,并且正在递归地尝试根据以下行对自身进行评估:

              if (!visible) {
                  viewModel.users.remove(this);
              }
      
      因此,这会创建对viewModel.users的依赖,因为remove必须访问ObservalArray的底层数组才能删除用户。在修改阵列时,将通知订阅服务器,其中一个订阅服务器将是它自己

      一般来说,最好不要改变DependentToServable中任何可观察对象的状态。您可以手动订阅对DependentToServable的更改,并在那里进行更改(前提是DependentToServable不依赖于您正在更改的内容)

      但是,在本例中,我可能会在viewModel级别创建一个DependentToServable,名为
      filteredUsers
      。然后,返回已筛选的用户数组的版本

      可能是这样的:

      viewModel.filteredUsers = ko.dependentObservable(function() {
          var selected = viewModel.selectedKeyword();
          //if nothing is selected, then return an empty array
          return !selected ? [] : ko.utils.arrayFilter(this.users(), function(user) {
              //otherwise, filter on keywords.  Stop on first match.
              return ko.utils.arrayFirst(user.keywords(), function(keyword) {
                  return keyword === selected;
              }) != null; //doesn't have to be a boolean, but just trying to be clear in sample
          });
      }, viewModel);
      
      您也不应该需要脏标志,因为DependentToServables将在其访问的任何观察对象发生更改时重新触发。因此,由于它访问selectedKeyword,因此每当selectedKeyword发生更改时,它都会得到重新评估


      我希望我能正确理解您的情景。

      完美的答案,非常有魅力!你完全改变了我对淘汰赛的看法:)
      viewModel.filteredUsers = ko.dependentObservable(function() {
          var selected = viewModel.selectedKeyword();
          //if nothing is selected, then return an empty array
          return !selected ? [] : ko.utils.arrayFilter(this.users(), function(user) {
              //otherwise, filter on keywords.  Stop on first match.
              return ko.utils.arrayFirst(user.keywords(), function(keyword) {
                  return keyword === selected;
              }) != null; //doesn't have to be a boolean, but just trying to be clear in sample
          });
      }, viewModel);