2017-02-15 53 views
0

嗨我有一個問題,以創建正確的功能來顯示/隱藏元素。目標很簡單,當你點擊列表元素時,你會看到div(模板)和更多信息。現在你必須再次點擊這個相同的列表元素來隱藏這個元素。我想要做什麼: 例如,當我點擊列表中的第一個元素並且此元素的模板將顯示時,我轉到列表中的第二個元素(或最後一個或其他),然後單擊它,我想要隱藏所有打開的元素(模板),但我只想看到我單擊的元素的活動元素。現在我可以在同一時間打開許多元素,並且我想將其更改爲只打開活動元素並隱藏所有其他元素。這在knonckout中可以做到嗎?或者,也許我必須使用jQuery的呢?在jsfiddle淘汰賽隱藏所有不活躍的元素

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: 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> 

JS

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

回答

1

這當然是可能的淘汰賽。您只需將切換功能移至PersonInfoViewModel,然後在該循​​環內通過其他personInfo模型關閉它們。

self.toggleshowMoreInfo = function (person) { 
    var people = self.filteredPeople(); 
    for(var i=0; i<people.length; i++){ 
     if(people[i] !== person && people[i].showMoreInfo()){ 
      people[i].showMoreInfo(false); 
     } 
    } 
    person.showMoreInfo(!person.showMoreInfo());  
} 

然後改變你的點擊結合$parent.toggleshowMoreInfo

修訂jsFiddle

1

你可以通過使自己的點擊處理程序設置selectedPerson屬性大大簡化了這一點,並添加綁定到模板的div比較當前person對象到selectedPerson對象。這樣,你就不必做任何循環。淘汰賽將爲你做到這一切。例如。

<ul data-bind="foreach: filteredPeople"> 
    <li data-bind="click: toggleSelectedPerson"> 
     <span class="full-name" data-bind="text: fullName"></span> 
    </li> 
    <div data-bind="slideVisible: $parent.selectedPerson() === $data, fadeDuration:600,template: {name: 'person-template'}"></div> 
</ul> 

<div data-bind="foreach: filteredPeople"> 
    <div data-bind="slideVisible: $parent.selectedPerson() === $data, fadeDuration:600,template: {name: 'person-template'}"></div> 
</div> 

// your model config 
this.selectedPerson = ko.observable(null); 
this.toggleSelectedPerson = function (person) { 
    this.selectedPerson(this.selectedPerson() === person ? null : person); 
} 
// your model config continued... 

抓獲並更新的jsfiddle從另一個答案:https://jsfiddle.net/9swam66o/3/

+0

謝謝大家格雷厄姆這是非常有益的。 – mcmac