2015-08-25 4 views
-1

У меня есть вложенная структура данных, отображенная в массив в нокауте JS:Фильтрация в вложенном массиве

class Departments{ 
    string DepartmentName; 
    List<Group> groups 
} 
class Group{ 
    string groupName; 
    List<Person> persons; 
} 
class Person{ 
    String Firsname; 
    string LastName; 
} 

Я выбираемый данные с сервера и показать их в UI успешно. Но я хочу преобразовать массив в вычисленный в knockoutJS и отфильтровать его на FirstName и LastName. Стоит упомянуть, что я связал self.search_FirstName and self.search_LastName с двумя разными входами. HTML код для привязки данных выглядит следующим образом:

<div class="form-group"> 
    <input type="text" class="text-right text-success input-lg" placeholder="Name" data-bind="value:search_FirstName, valueUpdate: 'afterkeydown'" />  
</div> 


<div class="panel-group" id="accordion" data-bind="foreach: Profiles" role="tablist" aria-multiselectable="true"> 

    <div class="panel panel-default"> 
     <div class="panel-heading"> 
      <h4 class="panel-title" data-bind="text: DepartmentName"></h4> 
     </div> 

     <div class="panel-collapse collapse in"> 
      <div class="panel-body"> 
       <table data-bind="foreach: { data: GroupVMs }" class="table table-responsive col-lg-12 col-sm-12 col-md-12"> 
        <tbody> 
         <tr><td class="groups" data-bind="text: GroupName"></td></tr> 
         <tr> 
          <td> 
           <table data-bind="foreach: { data: PersonPhonesVMs }" class="table table-striped table-responsive col-lg-12 col-sm-12 col-md-12"> 
            <tr> 
             <td class="col-lg-1 col-sm-1 col-md-1" data-bind="text: Prefix"></td> 
             <td class="col-lg-2 col-sm-2 col-md-2" data-bind="text: FirstName"></td> 
             <td class="col-lg-3 col-sm-3 col-md-3" data-bind="text: LastName"></td>           
            </tr> 
           </table> 
          </td> 
         </tr> 
        </tbody> 
       </table> 
      </div> 
     </div> 

    </div> 
</div> 

Теперь я хочу во время ввода текста в текстовом поле search_FirstName данные автоматически фильтруется. Прямо сейчас я могу фильтровать записи на основе DepartmentName со следующим кодом:

self.Profiles = ko.computed(function() { 
     return ko.utils.arrayFilter(self.BackupProfiles(), function (rec) { 
      return (
       (self.search_FirstName().length == 0 || rec.DepartmentName.indexOf(self.search_FirstName()) > -1) 
      ); 
     }); 
    }); 

Кто-нибудь имеет какие-либо идеи для фильтрации записей, основанный на ПгвЬЫате и LastName полей?

+0

Ваш текущий код для меня не имеет смысла. Почему вы сравниваете 'DepartmentName' с' search_FirstName', это две разные вещи? Почему вы используете 'indexOf', а не' localeCompare'? Какова фактическая проблема с * задачей *, которую вы поставили в своем последнем предложении? Разве ты не можешь идти вперед и делать это? Попробуйте обновить свой вопрос более полным примером. – Jeroen

+0

PS. Я заменил тег asp.net-mvc «javascript». Я понимаю, что первый бит кода в настоящее время является C#, но я настоятельно рекомендую изменить его на javascript для вашего приложения, так как вопрос, похоже, не имеет ничего общего с кодом на стороне сервера. Если бы это была ошибка, не стесняйтесь откат редактирования тега, но если да, то также уточните, как «asp.net-mvc» имеет отношение к вопросу. – Jeroen

+0

Я хочу показать, что я могу выполнить поиск на первом уровне, но не могу продолжить поиск на внутренних уровнях. сравнение search_FirstName и departmentName не имеет никакого смысла. – Mahmoud

ответ

1

Я создал a fiddle для вас. В основе computed лежит структура, подобная структуре Profiles, но включающая только согласованные записи.

vm.filteredProfiles = ko.computed(function() { 
    var first = vm.search_FirstName().toLocaleLowerCase(); 
    if (first === '') return vm.Profiles(); 
    var result = []; 
    ko.utils.arrayForEach(vm.Profiles(), function (dept) { 
     var groupsMatched = []; 
     ko.utils.arrayForEach(dept.GroupVMs(), function (group) { 
      var personsMatched = []; 
      ko.utils.arrayForEach(group.PersonPhonesVMs(), function (person) { 
       if (person.FirstName().toLocaleLowerCase().indexOf(first) > -1) { 
        personsMatched.push(person); 
       } 
      }); 
      if (personsMatched.length > 0) { 
       groupsMatched.push({ 
        GroupName: group.GroupName, 
        PersonPhonesVMs: personsMatched 
       }); 
      } 
     }); 
     if (groupsMatched.length > 0) { 
      result.push({ 
       DepartmentName: dept.DepartmentName, 
       GroupVMs: groupsMatched 
      }); 
     } 
    }); 

    return result; 
}); 
+0

Спасибо, человек !!! вы спасли меня. – Mahmoud

0

Если я правильно понял, вы хотите «сгладить» всю структуру, так что у вас есть массив людей с полями «Имя_файла» и «Имя_группы». Для работы computed каждый уровень вашей исходной структуры должен быть observableArrays. Рассчитанный будет что-то вроде:

var flattenedPeople = ko.computed(function() { 
    var result = []; 
    ko.utils.arrayForEach(self.BackupProfiles(), function (dept) { 
     ko.utils.arrayForEach(dept.groups(), function (group) { 
     ko.utils.arrayForEach(group.persons(), function (person) { 
      result.push({ 
      DepartmentName: dept.DepartmentName, 
      GroupName: group.GroupName, 
      FirstName: person.FirstName, 
      LastName: person.LastName 
     }); 
     }); 
    }); 
    return result; 
}); 

Тогда вы могли бы сделать вычисляемый, что будет соответствовать на FirstName и/или LastName:

self.filteredPeople = ko.computed(function() { 
    var first = self.search_FirstName(), 
     last = self.search_LastName(); 
    return ko.utils.arrayFilter(flattenedPeople(), function (rec) { 
    return (first === '' || rec.FirstName === first) && 
     (last === '' || rec.LastName === last); 
    }); 
}); 
+2

Возможно, вы могли бы улучшить фактические условия поиска на что-то вроде '! First || rec.FirstName.toLocaleLowerCase(). indexOf (первый)> -1'. – Jeroen

+0

@Roy J: спасибо !!! но я не хочу сгладить весь массив. Я хочу сохранить структуру как есть и искать людей по их имени. наконец, удалите все отделы и/или группы, у которых нет соответствующего человека. – Mahmoud

+0

Вы не теряете исходную структуру, вычисляя ее. Вы можете использовать 'filterPeople' в другом, вычисленном для фильтрации департаментов и групп. Создайте необходимые инструменты. Если вы включите HTML и как хотите, чтобы он работал, я могу дать вам более конкретную помощь. –