ons-splitter-sideにユーザ一覧が表示され、ユーザ名をタップするとons-splitter-contentにスケジュールが表示される。
というのを作る際にハマったのでメモ。
記事の対象者
- 自分
- AngularJS 1.5のComponentを使っている人
- OnsenUI 2 Beta.8以降でons-splitterを使っている人
問題
ons-splitterを使って固定のページを表示するのはできるが、遷移先の画面へパラメータ(この場合はユーザ情報)を渡す方法がわからない。
ons-navigatorを使っている訳ではないのでnavigator.getCurrentPage()からオプションを拾うこともできない。
もしパラメータを渡せるとしたら、ons-splitter-contentのページを再読込するのはどうするのが良いか。
解決策
ons-splitter-contentに直接パラメータを渡すことはできないので、Angularコンポーネントのbindingsに$ctrl経由でオブジェクトを渡す。画面遷移&再読込はons-splitter-contentのloadを呼ぶ。
方法
メインの画面はこちら。大体の構成は公式のサンプル通り。
<ons-page>
<!-- スプリッタ -->
<ons-splitter var="splitter">
<ons-splitter-side animation="default" var="side" page="menu.html" side="left" collapse="portrait" swipeable swipe-target-width="50px" width="200px"></ons-splitter-side>
<ons-splitter-content var="content" page="page.html"></ons-splitter-content>
</ons-splitter>
<!-- メニュー -->
<ons-template id="menu.html">
<ons-list id="default-category-list">
<ons-list-header>ユーザ</ons-list-header>
<ons-list-item tappable modifier="chevron" class="list-item-container" ng-repeat="user in $ctrl.userList" ng-click="$ctrl.show(user)">{{user.name}}</ons-list-item>
</ons-list>
</ons-template>
<!-- コンテンツ -->
<ons-template id="page.html">
<ons-toolbar>
<div class="left">
<ons-toolbar-button ng-click="$ctrl.side.toggle()">
<ons-if platform="android">
<ons-icon icon="md-menu"></ons-icon>
</ons-if>
<ons-if platform="ios other">
<ons-icon icon="ion-navicon" style="font-size: 32px; width: 1em;"></ons-icon>
</ons-if>
</ons-toolbar-button>
</div>
<div class="center">{{$ctrl.user.name}}</div>
</ons-toolbar>
<!-- スケジュール一覧コンポーネントに渡す -->
<schedule-list user="$ctrl.user"></schedule-list>
</ons-template>
</ons-page>
コントローラ全部は多いので必要なところだけ。
ons-splitter-contentにvarを設定し、content.load()を呼んでテンプレートを再読み込みしている。
// ユーザ一覧表示
function show(user) {
vm.user = user;
vm.content.load('page.html');
vm.side.close();
}
// 初期化
ons.ready(function() {
$timeout(function() {
vm.side = $window.side;
vm.content = $window.content;
vm.loadUserList();
});
});
vm.user
は画面の読み込み時に<schedule-list user="$ctrl.user">
としてコンポーネントに渡される。
bindingsは単方向バインディングを指定する。
// コンポーネントオブジェクト
var component = {
bindings : {
user : '<'
},
controller : Controller,
templateUrl : 'src/components/schedule-list/schedule-list.template.html'
}
// コンポーネント登録
app.component('scheduleList', component);
content.load()がオプション指定を受け付けてくれればこんな面倒な事にはならないのに。
全部一枚のソースに書く のが一番楽だがコンポーネント指向が崩れる。ぐぬぬ。
結論
ons-splitter-contentにパラメータを渡すことは出来ない。
$ctrl経由でコンポーネントにパラメータを渡した方が良い。
ons-splitter関連は苦労する。