AngularJS服务器端多列搜索

时间:2017-11-16 21:51:53

标签: angularjs node.js search

我正在NodeJS和AngularJS中构建一个应用程序。

我正在构建一个多列搜索功能,用户可以将搜索关键字输入到单独的搜索框中(位于每列的顶部),并根据列检索结果。

enter image description here

到目前为止,我只有一个搜索框可以同时搜索所有属性。

如何实现多个基于多个属性返回结果的搜索框?

注意:出于性能原因,我想在服务器端实现此功能。 (我知道我可以简单地使用HTML属性| filter:column1 | filter:column2但是如果可能的话就想避免使用这种技术。)

这是我到目前为止的代码。我想我需要传递一些在视图上设置的“searchBy”变量,然后更新搜索方法以通过多个查询/属性对进行搜索。

//Search service factory
    //Initialize filtered items and get search results
    function search(items, query) {
      this.filteredItems = $filter('filter')(items, function (item) {
        for(var attr in item) {
          if (searchMatch(item[attr], query))
            return true;
        }
        return false;
      });
      return this.filteredItems;
    }

    function searchMatch(haystack, needle) {
      if (!needle) {
        return true;
      }
      return haystack.toString().toLowerCase().indexOf(needle.toLowerCase()) !== -1;
    };

//Controller
  vm.filteredItems = vm.search(vm.unfilteredItems, vm.query);

//View
  input(type='text', ng-model='vm.query', ng-change='vm.search(vm.unfilteredItems, vm.query)', placeholder='Search')

1 个答案:

答案 0 :(得分:0)

我能够通过首先为每个搜索框创建一个对象数组然后使用ng-repeat属性在视图中重复这些框来解决这个问题。

//Controller
var vm = this;
var vm.unfilteredItems; //data source query removed for brevity

//Initialize search inputs
vm.search_by_inputs = [
  {search_column: 'id', search_query: ''},
  {search_column: 'requester', search_query: ''},
  {search_column: 'dataowner', search_query: ''}
];

function initSearch() {
  vm.filtered_items = vm.search(vm.unfiltered_items, vm.search_by_inputs);
}

//View
input.input-large.search-query(type='text', value='{{search_by.search_query}}', ng-model='search_by.search_query' ng-change='vm.initSearch()', placeholder='Search')

下一步是循环控制器中的search_by_inputs对象并创建一个新对象,其中只有输入的搜索值输入到视图中的搜索框中。然后在搜索方法中内置"过滤器"组件迭代每个项目,并在该循环内部检查每个搜索项,并使用与该属性匹配的列名称检查该值。

/*
 * Create new array of objects with only elements that have search values to optimize loop inside filter
 * @search_by_inputs array of objects each has a key search_column and a value search_query
 */
function optimizeSearchProperties(search_by_inputs) {
  search_by_properties = [];

  for (var i = 0, len = search_by_inputs.length; i < len; i++) {
    //If this column input box has query text
    if (search_by_inputs[i].search_query) {
      search_by_properties.push(search_by_inputs[i]);
    }
  }
  return search_by_properties;
}

/*
 * @haystack search item
 * @needle search term
 */
function searchMatch(haystack, needle) {
  if (!needle) {
    return true;
  }

  return haystack.toString().toLowerCase().indexOf(needle.toLowerCase()) !== -1;
}

/*
 * Create filtered items object by filtering search results
 * @items original array of objects returned by database query result
 * @search_by_inputs array of objects each has a key search_column and a value search_query
 */
function search(items, search_by_inputs) {
  var search_by_properties = optimizeSearchProperties(search_by_inputs);

  //If there are no search properties input by requester then return all items
  if (search_by_properties.length === 0) {
    this.filtered_items = items;
    return this.filtered_items;
  }

  this.filtered_items = $filter('filter')(items, function (item) {
    var search_result = true;
    //Loop over all search by input textboxes
    for (var n = 0, len = search_by_properties.length; n < len; n++) {
      //If there is no query text
      if (!search_by_properties[n].search_query) {
        //Continue to next element in array
        continue;
        //Else if element has a property that matches search input column name
      } else if (item[search_by_properties[n].search_column]) {
          if (!searchMatch(item[search_by_properties[n].search_column], search_by_properties[n].search_query)) {
            search_result = false;
            break;
          }
      }
    }
    return search_result;
  });
  return this.filtered_items;
}

我很乐意在优化,性能,技术等方面对此解决方案提供一些反馈。谢谢!