$location.path
で ngRoute のルートを変更してコントローラーが切り替わるときに遷移前のコントローラーから遷移後のコントローラーに値を受け渡す方法。
遷移前を A、遷移後を B とすると、A で $location.path()
を呼んだときに A の $scope
で $routeChangeStart
イベントを拾って遷移先のルート(イベントハンドラの第2引数)の params
に値を設定し、B のコンストラクタで $routeParams
から値を取り出します。
<!doctype html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<meta name="description" content="qiita route forward value" />
<link href="//getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet" type="text/css" />
<title>AngularJS Example</title>
<style>
.view {
position: absolute;
left: 20px;
right: 20px;
}
</style>
</head>
<body id="body">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#/">AngularJS Example</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="#/aaa">aaa</a></li>
<li><a href="#/bbb">bbb</a></li>
</ul>
</div>
</div>
</nav>
<div id="main">
<div class="view" ng-view></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.min.js"></script>
<script type="text/ng-template" id="/aaa">
<input type="text" ng-model="val">
<button class="btn btn-info" ng-click="click()">Click</button>
</script>
<script type="text/ng-template" id="/bbb">
val: {{ val }}
</script>
<script>
'use strict';
var app = angular.module('app', ['ngRoute']);
app.config(function($routeProvider){
$routeProvider.when('/aaa', {
templateUrl: '/aaa',
controller: function($scope, $location){
$scope.click = function(){
$location.path('/bbb');
$scope.$on('$routeChangeStart', function(ev, current){
current.params.val = $scope.val;
});
};
}
});
$routeProvider.when('/bbb', {
templateUrl: '/bbb',
controller: function($scope, $routeParams){
$scope.val = $routeParams.val;
}
});
$routeProvider.otherwise({redirectTo: '/aaa'});
});
</script>
</body>
</html>
デモ
試行錯誤の跡
- サービスで共有する
- 単に値を受け渡すだけでサービスを作るのもどうかなー
- A で
$broadcast()
して B のコンストラクタで$on
で拾う- A の
$broadcast()
の時点ではまだ B のコンストラクタが呼ばれていないので拾えない
- A の
- A で
$routeChangeSuccess
イベントで B のスコープに直接突っ込む- イベントが拾えなかった
-
$routeChangeSuccess
の時点で A の$scope
のイベントがアンバインドされているから?
- B のコンストラクタで
$routeChangeSuccess
を拾ってprevious
のscope
から値を取り出す- 一応できた、js のコードは次のようになる
var app = angular.module('app', ['ngRoute']);
app.config(function($routeProvider){
$routeProvider.when('/aaa', {
templateUrl: '/aaa',
controller: function($scope, $location){
$scope.click = function(){
$location.path('/bbb');
};
}
});
$routeProvider.when('/bbb', {
templateUrl: '/bbb',
controller: function($scope, $routeParams){
$scope.$on('$routeChangeSuccess', function(ev, current, previous){
$scope.val = previous.scope.val;
});
}
});
$routeProvider.otherwise({redirectTo: '/aaa'});
});