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];
}
};
});
いかがだったでしょうか?
良かったら、是非、参考にしてください。