コントローラ間でデータを共有しようとしています。ユースケースは複数ステップのフォームで、1つの入力で入力されたデータは後で元のコントローラ外の複数の表示場所で使用されます。以下のコードとjsfiddleはこちら。
html
<div ng-controller="FirstCtrl">
<input type="text" ng-model="FirstName"><!-- Input entered here -->
<br>Input is : <strong>{{FirstName}}</strong><!-- Successfully updates here -->
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{FirstName}}<!-- How do I automatically updated it here? -->
</div>
JS
// declare the app with no dependencies
var myApp = angular.module('myApp', []);
// make a factory to share data between controllers
myApp.factory('Data', function(){
// I know this doesn't work, but what will?
var FirstName = '';
return FirstName;
});
// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){
});
// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
$scope.FirstName = Data.FirstName;
});
どのような助けでも大歓迎です。
ベストアンサー1
簡単な解決策は、ファクトリにオブジェクトを返させ、コントローラが同じオブジェクトへの参照を使用して動作するようにすることです。
JS:
// declare the app with no dependencies
var myApp = angular.module('myApp', []);
// Create the factory that share the Fact
myApp.factory('Fact', function(){
return { Field: '' };
});
// Two controllers sharing an object that has a string in it
myApp.controller('FirstCtrl', function( $scope, Fact ){
$scope.Alpha = Fact;
});
myApp.controller('SecondCtrl', function( $scope, Fact ){
$scope.Beta = Fact;
});
HTML:
<div ng-controller="FirstCtrl">
<input type="text" ng-model="Alpha.Field">
First {{Alpha.Field}}
</div>
<div ng-controller="SecondCtrl">
<input type="text" ng-model="Beta.Field">
Second {{Beta.Field}}
</div>
デモ: http://jsfiddle.net/HEdJF/
アプリケーションが大きくなり、複雑になり、テストが難しくなると、このようにファクトリからオブジェクト全体を公開するのではなく、代わりにゲッターやセッターなどを介して制限されたアクセスを許可することが必要な場合があります。
myApp.factory('Data', function () {
var data = {
FirstName: ''
};
return {
getFirstName: function () {
return data.FirstName;
},
setFirstName: function (firstName) {
data.FirstName = firstName;
}
};
});
このアプローチでは、新しい値でファクトリを更新し、変更を監視して取得するのは、コンシューマ コントローラの責任です。
myApp.controller('FirstCtrl', function ($scope, Data) {
$scope.firstName = '';
$scope.$watch('firstName', function (newValue, oldValue) {
if (newValue !== oldValue) Data.setFirstName(newValue);
});
});
myApp.controller('SecondCtrl', function ($scope, Data) {
$scope.$watch(function () { return Data.getFirstName(); }, function (newValue, oldValue) {
if (newValue !== oldValue) $scope.firstName = newValue;
});
});
HTML:
<div ng-controller="FirstCtrl">
<input type="text" ng-model="firstName">
<br>Input is : <strong>{{firstName}}</strong>
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{firstName}}
</div>