この記事は、Onsen UI Advent Calendar 2016 の14日目の記事として作成しました。
※このバグはOnsen UI 2.0.5以降で修正されています
※Angular2バインディングではまだ起こるようです(https://github.com/OnsenUI/OnsenUI/issues/1815)
はじめに
「#1565は2.0.1で修正すると言ったな」
「そ、そうだ、アシアルさんっ...早く直しt...」
「あれは嘘だ」
「ウウウアァアアアア!」
以前取り上げたons-carouselのバグの改修は進んでいないようです。
しかし、アプリは作らねばならない。
動作環境
- OnsenUI 2.0.4
- AngularJS 1.5.9
- Android 5.1.1
- iOS 10.1
問題
ons-carouselを使用する際、
- ons-carouselをスワイプしてカルーセルの現在位置を変える
- pushPage()で別のページに遷移
- 遷移後のページでAndroidならキーボード表示、iOSなら画面を横に傾ける
- popPage()で遷移前のページに戻る
と操作すると、カルーセルの位置が初期値(index=0)に戻ってしまいます。
解決方法
まず、postchange
イベントが発生したらカルーセルの表示位置を保存します。
インデックス初期化バグはページ遷移後に発生するので、それ用のフラグpagePushed
を準備します。
vm.carousel.on('postchange', function(event) {
if (pagePushed) {
needFix = true; // バグ発生を検知
} else {
lastIndex = event.activeIndex;
}
});
ページ遷移後、カルーセルが表示されていないにも関わらずpostchange
イベントが発火した場合は「バグが発生した」とみなします。
次にページ遷移の実行部分の処理です。
var options = {
prePop: checkCarouselBug,
};
navi.pushPage('detail.html').then(function() {
pagePushed = true;
});;
バグ発生時にカルーセルの位置を戻す動作をpushPage()
の引数として渡すと、遷移先のページで呼び出すことが可能です。
function checkCarouselBug() {
pagePushed = false;
if (needFix) {
needFix = false;
$timeout(function() {
vm.carousel.setActiveIndex(lastIndex); // 復元
});
}
}
最後に、遷移後のページでpopPage()
の直前にバグチェックを実行します。
function back() {
var options = {};
args.prePop(); // バグチェック&インデックス復元
navi.popPage(options);
}
これでOK!
おわりに
ページ毎にインデックス復元を実行しないといけなくなるので、あまり良い方法とは言えませんが、とりあえず現状はこれで対応可能です。
今回の修正の内容は以下で確認可能です。
http://codepen.io/puku0x/pen/WogwRg
※ 遷移後ページの戻るボタンの表示が崩れていますがv2.0.4の不具合のようです