Edited at

AngularJS の ngRoute でコントローラー切り替え時に値を受け渡す

More than 5 years have passed since last update.

$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>


デモ

Demo


試行錯誤の跡


  • サービスで共有する


    • 単に値を受け渡すだけでサービスを作るのもどうかなー



  • A で $broadcast() して B のコンストラクタで $on で拾う


    • A の $broadcast() の時点ではまだ B のコンストラクタが呼ばれていないので拾えない



  • A で $routeChangeSuccess イベントで B のスコープに直接突っ込む


    • イベントが拾えなかった


    • $routeChangeSuccess の時点で A の $scope のイベントがアンバインドされているから?



  • B のコンストラクタで $routeChangeSuccess を拾って previousscope から値を取り出す


    • 一応できた、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'});
});