2015-12-01 41 views
0

如何在搜索條件中包含子數組?

var Foo = function() { 
 
    var self = this; 
 
    self.name = ko.observable(); 
 
    self.age = ko.observable(); 
 
    self.gender = ko.observable(); 
 
    self.childs = ko.observableArray([]); 
 
}; 
 

 
var Child = function() { 
 
    var self = this; 
 
    self.childName = ko.observable(); 
 
}; 
 

 
var data = [ 
 
    { name: 'Foo1', age: 21, gender: 'Male', childs: [{ name: 'Child1' }, { name: 'AnotherChild1' }] }, 
 
    { name: 'Foo2', age: 22, gender: 'Female', childs: [{ name: 'Child2' }, { name: 'AnotherChild2' }] }, 
 
    { name: 'Foo3', age: 23, gender: 'Male', childs: [{ name: 'AnotherChild3' }] }, 
 
    ]; 
 

 
var vm = (function() { 
 
    var foos = ko.observableArray([]), 
 
     init = function() { 
 
     for(var i = 0;i < data.length; i++) { 
 
      var newFoo = new Foo() 
 
        .name(data[i].name) 
 
        .age(data[i].age) 
 
        .gender(data[i].gender); 
 
      
 
      for(var j = 0; j < data[i].childs.length; j++) { 
 
      newFoo.childs.push(new Child() 
 
          .childName(data[i].childs[j].name)); 
 
      } 
 
      
 
      foos.push(newFoo); 
 
     } 
 
     }, 
 
     startsWith = function (str, prefix) { 
 
     if(str) return (!prefix || str.slice(0, prefix.length).toLowerCase() === prefix.toLowerCase()) 
 
     return; 
 
     }, 
 
     searchTerm = ko.observable(), 
 
     filterFoos = ko.computed(function() { 
 
     return ko.utils.arrayFilter(foos(), function(item) { 
 
      return (startsWith(item.name(), searchTerm())); 
 
     }); 
 
     }); 
 
    
 
    return { 
 
    foos: foos, 
 
    init: init, 
 
    searchTerm: searchTerm, 
 
    filterFoos: filterFoos 
 
    } 
 
}()); 
 

 

 
vm.init(); 
 
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<input type="text" data-bind="value: $root.searchTerm" /> 
 
<span data-bind="text: $root.searchTerm"></span> 
 
<pre data-bind="text: ko.toJSON($root.searchTerm, null, 2)"></pre> 
 
<pre data-bind="text: ko.toJSON($root.filterFoos, null, 2)"></pre>

我有以上代碼段中運行,並期待,看看它是否有任何的搜索條件。現在,我如何在搜索條件中包含childs數組?我想知道如果我在文本框中輸入值,它也會查看childs數組以查看它是否存在。

請讓我知道如果我需要澄清的事情進一步

任何幫助將非常感激。由於

回答

1

新增遞歸在項目的所有孩子的

var Foo = function() { 
 
    var self = this; 
 
    self.name = ko.observable(); 
 
    self.age = ko.observable(); 
 
    self.gender = ko.observable(); 
 
    self.childs = ko.observableArray([]); 
 
}; 
 

 
var Child = function() { 
 
    var self = this; 
 
    self.childName = ko.observable(); 
 
}; 
 

 
var data = [ 
 
    { name: 'Foo1', age: 21, gender: 'Male', childs: [{ name: 'Child1' }, { name: 'AnotherChild1' }] }, 
 
    { name: 'Foo2', age: 22, gender: 'Female', childs: [{ name: 'Child2' }, { name: 'AnotherChild2' }] }, 
 
    { name: 'Foo3', age: 23, gender: 'Male', childs: [{ name: 'AnotherChild3' }] }, 
 
    ]; 
 

 
var vm = (function() { 
 
    var foos = ko.observableArray([]), 
 
     init = function() { 
 
     for(var i = 0;i < data.length; i++) { 
 
      var newFoo = new Foo() 
 
        .name(data[i].name) 
 
        .age(data[i].age) 
 
        .gender(data[i].gender); 
 
      
 
      for(var j = 0; j < data[i].childs.length; j++) { 
 
      newFoo.childs.push(new Child() 
 
          .childName(data[i].childs[j].name)); 
 
      } 
 
      
 
      foos.push(newFoo); 
 
     } 
 
     }, 
 
     startsWith = function (item, prefix) { 
 
var str = item.name? item.name():item.childName(); 
 
     if(str) return (!prefix || str.slice(0, prefix.length).toLowerCase() === prefix.toLowerCase()) || 
 
(item.childs && ko.utils.arrayFilter(item.childs(),function(child){ 
 
return startsWith(child,prefix); 
 
}).length>0); 
 
     return; 
 
     }, 
 
     searchTerm = ko.observable(), 
 
     filterFoos = ko.computed(function() { 
 
     return ko.utils.arrayFilter(foos(), function(item) { 
 
      return (startsWith(item, searchTerm())); 
 
     }); 
 
     }); 
 
    
 
    return { 
 
    foos: foos, 
 
    init: init, 
 
    searchTerm: searchTerm, 
 
    filterFoos: filterFoos 
 
    } 
 
}()); 
 

 

 
vm.init(); 
 
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<input type="text" data-bind="value: $root.searchTerm" /> 
 
<span data-bind="text: $root.searchTerm"></span> 
 
<pre data-bind="text: ko.toJSON($root.searchTerm, null, 2)"></pre> 
 
<pre data-bind="text: ko.toJSON($root.filterFoos, null, 2)"></pre>

+0

一個問題進行搜索。是否可以堅持'childName'? –

+0

我已經用childName更新了答案。我仍然認爲保持名稱一致將有利於你。 –

+0

哦,我明白了。我會採取你的建議。謝謝。你認爲你可以進一步闡述?如果我保持它們一樣,是否與性能有關? –

相關問題