基本的に、ユーザーが非表示/表示ボタンをクリックすると、その下にあるリスト要素の表示を切り替えたいように、カスタムバインディングを作成しようとしています。
現時点では、基本的に非表示の要素 (this.showGalaxys を false に設定) から始めて、表示される非表示/表示をクリックすると、部分的に動作させることができます。しかし、逆は起こりません。つまり、現在表示されているリスト要素を非表示にすることはできません。
銀河セクションと同じ実装を使用するため、銀河セクションの後の要素は無視します。
また、HTML の早い段階でこれらのオブジェクトにデータをバインドしていることにも注意してください。これはすべて正しく機能しています。唯一の問題は、要素の表示を切り替えるためのロジックです。
私のHTMLマークアップの関連セクションは次のとおりです。
デモ: jsFiddle
<h2>Results</h2>
<br/>
<div data-bind="foreach: universes">
<strong style="color: tomato">Universe: </strong><span data-bind="text: name"></span>
<br/><br/>
<div style="padding-left: 20px">
<strong style="color: teal; padding-right: 20px">Galaxys</strong><button data-bind="click: toggleGalaxys">Show/Hide</button>
<ul data-bind="fadeVisible: displayGalaxys">
<div data-bind="foreach: galaxys">
<li data-bind="text: name"></li>
<div style="padding-left: 20px">
<strong style="color: sandybrown; padding-right: 20px">Star System</strong><button data-bind="fadeVisible: showStarSystems">Show/Hide</button>
<ul id="starSystemsList">
<div data-bind="foreach: starSystems">
<li data-bind="text: name"></li>
<div style="padding-left: 20px">
<strong style="color: purple; padding-right: 20px">Planets</strong>
<ul>
<div data-bind="foreach: planets">
<li data-bind="text: name"></li>
</div>
</ul>
</div>
</div>
</ul>
</div>
</div>
</ul>
</div>
</div>
使用されているJavascriptコードは次のとおりです。
function UniverseViewModel() {
var self = this;
self.universes = ko.observableArray();
self.addUniverse = function() {
self.universes.push(new Universe(""));
};
}
function Universe(name) {
this.name = ko.observable(name);
this.galaxys = ko.observableArray();
this.addGalaxy = function() {
this.galaxys.push(new Galaxy(""));
};
this.displayGalaxys = ko.observable(false);
this.toggleGalaxys = function () {
this.displayGalaxys = !this.displayGalaxys;
};
}
function Galaxy(name) {
this.name = ko.observable(name);
this.starSystems = ko.observableArray();
this.addStarSystem = function() {
this.starSystems.push(new StarSystem(""));
};
this.showStarSystems = ko.observable(false);
}
function StarSystem(name) {
this.name = ko.observable(name);
this.planets = ko.observableArray();
this.addPlanet = function() {
this.planets.push(new Planet(""));
};
this.removePlanet = function(planet) {
this.planets.remove(planet);
};
this.showPlanets = ko.observable(false);
}
function Planet(name) {
this.name = ko.observable(name);
}
ko.bindingHandlers.fadeVisible = {
init: function (element, valueAccessor) {
var value = valueAccessor();
$(element).toggle(ko.utils.unwrapObservable(value));
},
update: function(element, valueAccessor) {
var value = valueAccessor();
ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
}
};
ko.applyBindings(new UniverseViewModel());