2017-02-03 61 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