2017-02-15 18 views
0

こんにちは私は、要素を表示/非表示するための正しい関数を作成する問題があります。目標はリスト要素をクリックすると簡単になります。詳細はdiv(テンプレート)と表示されます。この要素を非表示にするには、同じリスト要素を再度クリックする必要があります。私がしたいこと: 例:リストの最初の要素をクリックし、この要素のテンプレートが表示されたら、リスト上の2番目の要素(または最後か他のいずれか)に移動します。開いている要素(テンプレート)をすべて非表示にしますが、クリックした要素のアクティブな要素のみを表示したいとします。今私はこの同じ時間に多くの要素を開くことができ、開いている唯一のアクティブな要素のためにそれを変更し、すべての残りを隠したいと思います。これはknockckoutで行うことができますか?それとも、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

これはノックアウトで確かに可能です。必要なのは、Toggle関数を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());  
} 

その後、あなたはあなたのクリックハンドラがselectedPersonプロパティを設定することによって、大幅にこれを簡素化し、比較するためのテンプレートのdiv要素に結合を追加することができjsFiddle

1

を改訂$parent.toggleshowMoreInfo

に結合し、あなたのクリックを変更現在の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

関連する問題