2017-02-03 60 views
2

我在淘汰赛中写了我的简单第一个例子,但我需要一点帮助两件事情。我搜索信息和微笑作品的例子,但我没有找到,所以我问你。 我需要在我的页面上添加简单搜索,我可以按名称和姓氏筛选结果。我的第一个问题是我如何做到这一点,因为我目前的解决方案向我展示了所有结果; (额外的问题是如何可以在一个查询中通过姓名和姓氏来过滤我的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

有很多方法可以做到这一点。我使用了一个可计算的可观察值来继续过滤人员数组,以删除那些不匹配的数组。

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); 
 
    }); 
 
<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>

+0

顺便说一句,我发现这个淘汰赛utils的页面开发过程中是非常有用的 - http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs .html它允许你保持jQuery淘汰大部分 – dmoo

+0

谢谢你的帮助和链接到文章。这是一个很好的例子,如果你知道在这篇文章中关于我的第二个问题的回答(关于标签),那么如何做搜索/过滤正确的方式,我会很满。 – mcmac