jQueryでアイテムを追加するときとか、slideUpしたりDownしたりfadeOutさせたりすることもあるでしょう。
knockout.jsでは通常のステップだけだと、いきなり追加されるか削除されるかしかありません。
<ul data-bind="foreach: items">
<li><span data-bind="text: value"></span></li>
</ul>
<input type="button" value="add" data-bind="click: addItem" />
<input type="button" value="remove" data-bind="click: removeItem" />
<script type="text/javascript">
$(function(){
var viewModel = {
items: ko.observableArray([]),
addItem: function () {
this.items.push({ value: 'hoge' });
},
removeItem: function () {
var last = this.items()[this.items().length-1];
this.items.remove(last);
}
};
ko.applyBindings(viewMpdel)
});
</script>
ここにアニメーションを入れる場合は、data-bind側の記述を大きく変える必要があります。
<ul data-bind="template: { foreach:items, afterAdd:showItem, beforeRemove:hideItem }">
<li><span data-bind="text: value"></span></li>
</ul>
template
を使用することで afterAdd
と beforeRemove
という追加後、削除前のイベントを拾うことが可能になります。
それぞれに対応しているイベントを定義しておきましょう。
var viewModel = {
// 省略
showItem: function (elem) {
if (elem.nodeType === 1) {
// 先に隠さないとアニメーションで表示できない
$(elem).hide().slideDown('fast');
}
},
hideItem: function () {
if (elem.nodeType === 1) {
$(elem).slideUp('fast', function() { $(elem).remove(); });
}
}
}
console.logを仕込むとわかりますが、別のnodeTypeでもコールバックされるイベントのようです。
なのでnodeTypeでチェックしてから、なんかしらの処理をするようにしましょう。