淘汰搜索过滤器不起作用

时间:2017-02-03 21:44:38

标签: jquery knockout.js

我在淘汰赛中写了我简单的第一个例子,但我需要一点帮助。我搜索熟悉的作品的信息和例子,但我没有找到,所以我问你。 我需要在我的页面上添加简单搜索,我可以按名称和姓氏过滤结果。我的第一个问题是如何才能做到这一点,因为我目前的解决方案向我展示了所有结果; (额外的问题我如何在一个查询中按名称和姓氏过滤我的json)? 我的第二个问题是标签结构,是不正确的。现在,当我点击li元素时,我将此元素的结果切换到容器,而不是隐藏所有当前打开的结果(simple example what I want to do);顺便说一句,我想为活动标签添加样式(example)。 可能是我的问题来自外部json,但我不确定。请查看我的代码我打开的解决方案比主要更好。

外部JSON(example.json)

[
  {
    "index": 0,
    "name": [{
      "first": "Barlow",
      "last": "Moore"
    }]
  },
  {
    "index": 1,
    "name": [{
      "first": "Valeria",
      "last": "Meadows"
    }]
  },
  {
    "index": 2,
    "name": [{
      "first": "Constance",
      "last": "Singleton"
    }]
  },
  {
    "index": 3,
    "name": [{
      "first": "Wilder",
      "last": "Steele"
    }]
  }
]

JS

$(document).ready(function() {
    ko.applyBindings(viewModel);
  });

  ko.bindingHandlers.slideVisible = {
    update: function(element, valueAccessor, allBindings) {
      var value = valueAccessor();
      var valueUnwrapped = ko.unwrap(value);
      var duration = allBindings.get('fadeDuration') || 400;
      if (valueUnwrapped == true)
        setTimeout(function(){ $(element).fadeIn(duration); }, duration);
      else
        $(element).fadeOut(duration);
    }
  };

  /* show all data from json */
  function PersonInfo(data) {
    this.firstName = ko.observable(data.name[0].first);
    this.lastName = ko.observable(data.name[0].last);
    this.fullName = ko.computed(function() {
      return this.firstName() + " " + this.lastName();
    }, this);

    this.showMoreInfo = ko.observable(false);
    this.toggleshowMoreInfo = function () {
      this.showMoreInfo(!this.showMoreInfo())
    }
  }

  function PersonInfoViewModel() {
    var self = this;
    self.personData = ko.observableArray([]);
    $.getJSON('example.json', function(allData) {
      var mappedPersonalData = $.map(allData, function(item) { 
        this.query = ko.observable('');
        var search = this.query().toLowerCase();
        if(item.name[0].first.toLowerCase().indexOf(search) >= 0) {

          return new PersonInfo(item) 
        }

      });
      self.personData(mappedPersonalData);
    });
  }

  var viewModel = new PersonInfoViewModel();

  <!-- template for presonal information -->
  <script type="text/html" id="person-template">
    <div class="col-xs-12 col-md-6">
      <p><span data-bind="text: fullName"></span></p>
    </div>
  </script>

HTML

<form action="#"> 
    <input placeholder="Search…" type="search" name="q" data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off"> 
  </form>

  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
        <ul class="name-list" data-bind="foreach: personData">
          <li data-bind="attr:{class: $index == 0 ? 'active' : ''}, click: toggleshowMoreInfo" role="button">
            <span class="full-name" data-bind="text: fullName"></span>
          </li>

          <div class="hidden-sm hidden-md hidden-lg" data-bind="slideVisible: showMoreInfo, fadeDuration:600,template: {name: 'person-template'}"></div>
        </ul>
      </div>

      <div class="col-xs-12 col-sm-6 col-md-8 col-lg-8 hidden-xs" data-bind="foreach: personData">
        <div class="row" data-bind="slideVisible: showMoreInfo, fadeDuration:600,template: {name: 'person-template'}""></div>
      </div>
    </div>
  </div>

1 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点。我使用一个计算的observable来保持过滤人的数组,以删除那些不匹配的人。

&#13;
&#13;
var data = [
  {
    "index": 0,
    "name": [{
      "first": "Barlow",
      "last": "Moore"
    }]
  },
  {
    "index": 1,
    "name": [{
      "first": "Valeria",
      "last": "Meadows"
    }]
  },
  {
    "index": 2,
    "name": [{
      "first": "Constance",
      "last": "Singleton"
    }]
  },
  {
    "index": 3,
    "name": [{
      "first": "Wilder",
      "last": "Steele"
    }]
  }
];

  var stringStartsWith = function (startsWith, string) {          
    string = string || "";
    if (startsWith.length > string.length)
        return false;
    return string.substring(0, startsWith.length) === startsWith;
  };

  ko.bindingHandlers.slideVisible = {
    update: function(element, valueAccessor, allBindings) {
      var value = valueAccessor();
      var valueUnwrapped = ko.unwrap(value);
      var duration = allBindings.get('fadeDuration') || 400;
      if (valueUnwrapped == true)
        setTimeout(function(){ $(element).fadeIn(duration); }, duration);
      else
        $(element).fadeOut(duration);
    }
  };

  /* show all data from json */
  function PersonInfo(data) {
    this.firstName = ko.observable(data.name[0].first);
    this.lastName = ko.observable(data.name[0].last);
    this.fullName = ko.computed(function() {
      return this.firstName() + " " + this.lastName();
    }, this);

    this.showMoreInfo = ko.observable(false);
    this.toggleshowMoreInfo = function () {
      this.showMoreInfo(!this.showMoreInfo())
    }
  }

  function PersonInfoViewModel() {
    var self = this;
    self.query = ko.observable('');
    self.mappedPersonalData = $.map(data, function(item) {  
      return new PersonInfo(item) 
    });
    self.filteredPeople = ko.computed(function () {
        return self.mappedPersonalData.filter(function (value) {
            if(self.query() === '' || self.query() === null){
               return true; //no query
            }
            if (stringStartsWith(self.query().toLowerCase(), value.firstName().toLowerCase()) || stringStartsWith(self.query().toLowerCase(), value.lastName().toLowerCase())){
               return true;
            }
            return false;
        });
    }); 
  }

  var viewModel = new PersonInfoViewModel();

  $(document).ready(function() {
    ko.applyBindings(viewModel);
  });
  
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<form action="#"> 
    <input placeholder="Search…" type="search" name="q" data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off"> 
  </form>

  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
        <ul class="name-list" data-bind="foreach: filteredPeople">
          <li data-bind="attr:{class: $index == 0 ? 'active' : ''}, click: toggleshowMoreInfo" role="button">
            <span class="full-name" data-bind="text: fullName"></span>
          </li>

          <div class="hidden-sm hidden-md hidden-lg" data-bind="slideVisible: showMoreInfo, fadeDuration:600,template: {name: 'person-template'}"></div>
        </ul>
        
      </div>

      <div class="col-xs-12 col-sm-6 col-md-8 col-lg-8 hidden-xs" data-bind="foreach: filteredPeople">
        <div class="row" data-bind="slideVisible: showMoreInfo, fadeDuration:600,template: {name: 'person-template'}"></div>
      </div>
    </div>
  </div>
 
                                                                                                                      
  <!-- template for presonal information -->
  <script type="text/html" id="person-template">
    <div class="col-xs-12 col-md-6">
      <p><span data-bind="text: fullName"></span></p>
    </div>
  </script>
&#13;
&#13;
&#13;