坊主が上手にHatenaに坊主のコードを書いた

ITBOZEによるIT技術の備忘録ブログ

AngularJSで、あるコントローラーから別のコントローラーの$scopeへアクセスする方法

グラハムさんの「ハッカーと画家」を読んで激しく共鳴。
で、最近、「Land of Lisp」を読破した(もちろん、手を動かしながらね!)。
そしたら、夢にまで、たくさんカッコが出てきてる。。。どーしよー。


どもっ、ITBOZEです。


さて、今日は、AngularJSを使った案件でのお話。


あるコントローラー内でのイベント(ボタン押下など)によって、別のコントローラー内にある文字列を変更したい。。。なんてこと、ありませんか?


このような場合、つまり、あるコントローラーから別のコントローラーの$scopeへアクセスしたい場合の方法について、ちょっとハマったので、早速メモ。


で、結論から言いますと、それぞれのコントローラーの$scopeを、Factoryで共有させればいいんです!


では、以下で説明しますね。


まず、具体例として、以下のHTMLがあるとします。

<ソース(1)>

<!doctype html>
<html ng-app="app">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
    <script src="app.js"></script>
</head>
<body>
 
<div ng-controller="ControllerA">
    <h2>ControllerA</h2>
    <button ng-click="buttonClick()">
        buttonClick on current scope
    </button>
    <button ng-click="buttonClickOnControllerB()">
        buttonClick on ControllerB's scope
    </button>
</div>
 
<div ng-controller="ControllerB">
    <h2>ControllerB</h2>
    <button ng-click="buttonClick()">
        buttonClick on current scope
    </button>
    <button ng-click="buttonClickOnControllerA()">
        buttonClick on ControllerA's scope
    </button>
</div>
</body>
</html>


で、app.jsは、以下のとおり。

<ソース(2)>

var app = angular.module('app', []);
 
app.controller('ControllerA', function ($scope) {
    $scope.variable1 = "ControllerAだよ";
 
    $scope.buttonClick = function () {
        console.log("ControllerA");
        console.log("$scope::variable1", $scope.variable1);
    };
});
 
app.controller('ControllerB', function ($scope) {
    $scope.variable1 = "ControllerBだよ";
 
    $scope.buttonClick = function () {
        console.log("ControllerB");
        console.log("$scope::variable1", $scope.variable1);
    };
});


そして、ControllerA内の$scopeと、ControllerB内の$scopeをお互いに共有させるには、以下のFactoryを作ります。

<ソース(3)>

app.factory('SharedScopes', function ($rootScope) {
    var sharedScopes = {};
 
    return {
        setScope: function (key, value) {
            sharedScopes[key] = value;
        },
        getScope: function (key) {
            return sharedScopes[key];
        }
    };
});


で、上記のソース(3)を、ソース(2)に取り込むと、以下の感じ。

var app = angular.module('app', []);
 
app.controller('ControllerA', function ($scope, SharedScopes) { ← ココ
    
    SharedScopes.setScope('ControllerA', $scope); ← ココ
    
    $scope.variable1 = "ControllerAだよ";

    ・・・   
});
 
app.controller('ControllerB', function ($scope, SharedScopes) { ← ココ
    
    SharedScopes.setScope('ControllerB', $scope); ← ココ

    $scope.variable1 = "ControllerBだよ";
 
    ・・・   
});



そして、今までの内容を全て記載した、app.jsは、以下の通り。

var app = angular.module('app', []);
 
app.controller('ControllerA', function ($scope, SharedScopes) {
 
    SharedScopes.setScope('ControllerA', $scope);
 
    $scope.variable1 = "ControllerAだよ";
 
    $scope.buttonClick = function () {
        console.log("ControllerA");
        console.log("ControllerA::variable1", Scopes.getScope('ControllerA').variable1);
        console.log("ControllerB::variable1", Scopes.getScope('ControllerB').variable1);
        console.log("$scope::variable1", $scope.variable1);
    };
 
    $scope.buttonClickOnControllerB = function () {
        Scopes.get('ControllerB').buttonClick();
    };
});
app.controller('ControllerB', function ($scope, SharedScopes) {
 
    SharedScopes.setScope('ControllerB', $scope);
 
    $scope.variable1 = "ControllerBだよ";
 
    $scope.buttonClick = function () {
        console.log("ControllerA");
        console.log("ControllerA::variable1", Scopes.getScope('ControllerA').variable1);
        console.log("ControllerB::variable1", Scopes.getScope('ControllerB').variable1);
        console.log("$scope::variable1", $scope.variable1);
    };
 
    $scope.buttonClickOnControllerA = function () {
        Scopes.get('ControllerA').buttonClick();
    };
});
app.factory('SharedScopes', function ($rootScope) {
    var sharedScopes = {};
 
    return {
        setScope: function (key, value) {
            sharedScopes[key] = value;
        },
        getScope: function (key) {
            return sharedScopes[key];
        }
    };
});


いかがだったでしょうか?

良かったら、是非、参考にしてください。

※Qiitaにも投稿しました。

AngularJSで、あるコントローラーから別のコントローラーの$scopeへアクセスする方法 - Qiita