1. ホーム
  2. javascript

[解決済み] AngularJS コントローラ間のデータ共有

2022-03-15 09:28:39

質問

コントローラ間でデータを共有しようとしています。使用例としては、複数ステップのフォームで、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;
});

何かお手伝いいただけることがあれば、ぜひお願いします。

解決方法は?

簡単な方法は、ファクトリーがオブジェクトを返すようにし、 コントローラが同じオブジェクトへの参照で動作するようにすることです。

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>

デモです。 http://jsfiddle.net/27mk1n1o/