AngularJS x UI-Routerの使い方
UI-Routerはとても強力で、ngRouterよりも多くの事ができるのでとても便利。 しかし、強力すぎてRouterの概念自体を塗り替えてしまっていてなかなかピンと来てなかったのでまとめてみる。
リストページと詳細ページを別々のページとして用意する
state-router.js
app.config(["$stateProvider", function ($stateProvider) { $stateProvider .state("list", { "url": "^/list", "templateUrl": "list.html", "controller": "ListCtrl" }) .state("detail", { "url": "^/detail/:detail_id", "templateUrl": "detail.html", "controller": "DetailCtrl" }) ; }])
index.html
<div ui-view></div>
list.html
<ul ng-repeat="content in contents"> <li><a href="#/detail/{{content.id}}">{{content.title}}</a></li> </ul>
detail.html
<dl> <dt>ID</dt> <dd>{{detail.id}}</dd> <dt>Title</dt> <dd>{{detail.title}}</dd> </dl>
リストと詳細がひとつのページの中にある
2カラムレイアウトでlistとdeitalを同じページの中に内包する。
state-router.js
app.config(["$stateProvider", function ($stateProvider) { $stateProvider .state("contents", { "templateUrl": "contents.html", "controller": "ContentsCtrl" }) .state("contents.detail", { "views": { "detail@contents": { "templateUrl": "detail.html", "controller": "DetailCtrl" } } }) ; }])
index.html
<div ui-view></div>
list.html
<nav class="left-column"> <ul ng-repeat="content in contents"> <li><a ui-sref="contents.detail({id: content.id})">{{content.title}}</a></li> </ul> </nav> <div class="right-column" ng-view="detail">
detail.html
<dl> <dt>ID</dt> <dd>{{detail.id}}</dd> <dt>Title</dt> <dd>{{detail.title}}</dd> </dl>
2カラムレイアウトでdetailをURLで指定できるようにする
/content
でリストとindexを、/content/{detail_id}
で指定したdetailを表示できるようにする。
state-router.js
app.config(["$stateProvider", function ($stateProvider) { $stateProvider .state("contents", { "url": "^/content", "templateUrl": "contents.html", "controller": "ContentsCtrl" }) .state("contents.detail", { "url": "/:id" "views": { "detail@contents": { "templateUrl": "detail.html", "controller": "DetailCtrl" } } }) ; }])
まとめ
- stateは継承が可能
.
で連結することで、親.子
というstateを定義できる
- viewsに
ビュー@ステート
を指定すると、親ステートで定義したui-view
にtemplateを埋め込むことができる - stateをネストした場合、URLは親のURLに追加される形で指定できる
^
からURLを開始する(^/content/:detail
というように)ことで相対ではなく絶対パスで指定できる
href
の代わりに、ui-sref
属性を用いることで、URLではなくstateをリンクに指定できる。ui-sref
を利用するばあい、$stateProviderに定義されてないstateを指定するとリンクにならない
UI-Routerの理解に一日費やしたので、とりあえず僕の理解の範囲をまとめた。 ややこしいけど大変便利!
AngularJSでdirectiveを作ってみる
2014-03-25
っていう文字列の日付をyear
, month
, day
の3つのフォームに分割して入力したい、と思った。
一つのngModelからフォーマットを変えてinputを並べればいいとおもって、directiveを使ってみた記録。
<input type="date" name="year" ng-model="user.birth_on"> <input type="date" name="month" ng-model="user.birth_on"> <input type="date" name="day" ng-model="user.birth_on">
directiveの作り方
ngModelController
に$formatters
というプロパティがArrayで存在するので、そいつにフォーマット用のfunctionを登録してやる。
- $filterを利用してdateを整形する
- 整形文字列は、
ui-date-format
の属性で指定できるようにする- 例)
ui-date-format="yyyy"
- 例)
- フォーマットする文字列はmodelから取ってくる
angular.module("app") .directive("uiDateFormat", [ "$filter", function ($filter) { return { restrict: "A", require: "ngModel", link: function (scope, element, attrs, ctrl) { ctrl.$formatters.push(function (view_value) { return $filter("date")(view_value, attrs.uiDateFormat); }); } } ]);
<input type="date" name="year" ng-model="user.birth_on" ui-date-format="yyyy"> <input type="date" name="month" ng-model="user.birth_on" ui-date-format="M"> <input type="date" name="day" ng-model="user.birth_on" ui-date-format="d">
ui-dateというAngular UIのライブラリ
ui-dateを使えばいいという気はしつつ、ui-dateはjquery-uiとjqueryに依存しているし、そこまでの機能は必要なさそうだった。 なので、勉強を兼ねて作ってみた。