LoginSignup
24
25

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-04-24

$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'});
});
24
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
25