アニメーション効果
このサンプルでは、アニメーションを実装する2つの方法を示します。
※訳者注
このサンプルは、コードのシンプルさにおいて問題があると訳者は考えております。
詳しくは サンプルに惑わされるな!KnockoutでUIエフェクトを使う際のベター・プラクティス をご覧ください。
-
template/foreachバインディングを使う場合、afterAddやbeforeRemoveにコールバックを指定することができます。 それによりエレメントの追加・削除に対してコードを介入させることができるため。 jQuery のslideUp/slideDown()やそれに類似するアニメーション手法を簡単に導入することができます。 惑星タイプを切り替えたり、惑星を追加することでこの動作を見ることができます。 -
Observable の値に従って任意の方法でエレメントの状態を操るカスタムバインディングを記述することは、難しくありません。 この例では、
fadeVisibleというカスタムバインディングを作成しています。 このカスタムバインディングは、 Observable の値が変化したときに 関連付けられた DOM エレメントをアニメーションさせるために jQuery のfadeIn/fadeOut関数を使います。 「オプションを表示」にチェックを入れたり、外したりしてをこの動作を確認して下さい。
デモ
惑星
表示:
コード: View
<h2>惑星</h2>
<p>
<label>
<input type='checkbox' data-bind='checked: displayAdvancedOptions' />
オプションを表示
</label>
</p>
<p data-bind='fadeVisible: displayAdvancedOptions'>
表示:
<label><input type='radio' name="type" value='all' data-bind='checked: typeToShow' />すべて</label>
<label><input type='radio' name="type" value='rock' data-bind='checked: typeToShow' />岩石惑星</label>
<label><input type='radio' name="type" value='gasgiant' data-bind='checked: typeToShow' />巨大ガス惑星</label>
</p>
<div data-bind='template: { foreach: planetsToShow,
beforeRemove: hidePlanetElement,
afterAdd: showPlanetElement }'>
<div data-bind='attr: { "class": "planet " + type }, text: name'> </div>
</div>
<p data-bind='fadeVisible: displayAdvancedOptions'>
<button data-bind='click: addPlanet.bind($data, "rock")'>岩石惑星を追加</button>
<button data-bind='click: addPlanet.bind($data, "gasgiant")'>巨大ガス惑星を追加</button>
</p>
コード: ViewModel
var PlanetsModel = function() {
this.planets = ko.observableArray([
{ name: "水星", type: "rock"},
{ name: "金星", type: "rock"},
{ name: "地球", type: "rock"},
{ name: "火星", type: "rock"},
{ name: "木製", type: "gasgiant"},
{ name: "土星", type: "gasgiant"},
{ name: "天王星", type: "gasgiant"},
{ name: "海王星", type: "gasgiant"},
{ name: "冥王星", type: "rock"}
]);
this.typeToShow = ko.observable("all");
this.displayAdvancedOptions = ko.observable(false);
this.addPlanet = function(type) {
this.planets.push({
name: "新惑星",
type: type
});
};
this.planetsToShow = ko.computed(function() {
// 惑星のリストを 条件 "typeToShow" でフィルタリングします。
var desiredType = this.typeToShow();
if (desiredType == "all") return this.planets();
return ko.utils.arrayFilter(this.planets(), function(planet) {
return planet.type == desiredType;
});
}, this);
// 惑星リスト用のアニメーション callback
this.showPlanetElement = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown() }
this.hidePlanetElement = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }) }
};
// jQuery の fadeIn() / fadeout() メソッドを使ってエレメントの 可視/不可視 を切り替えるカスタムばインディング
// 別のJSファイルに分割して読み込むこともできます。
ko.bindingHandlers.fadeVisible = {
init: function(element, valueAccessor) {
// 最初に、値に応じて即座にエレメントの 可視/不可視 を設定します。
var value = valueAccessor();
// Observable かどうかがわからない値は、"unwrapObservable" を使って処理することができます。
$(element).toggle(ko.utils.unwrapObservable(value));
},
update: function(element, valueAccessor) {
// 値の変化に応じて、ゆっくりと 可視/不可視 の切り替えを行います。
var value = valueAccessor();
ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
}
};
ko.applyBindings(new PlanetsModel());
jsFiddle で試す /
原文はこちら