331

2 つの Angular コントローラーがあります。

function Ctrl1($scope) {
    $scope.prop1 = "First";
}

function Ctrl2($scope) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

未定義のため、Ctrl1内部では使用できません。Ctrl2しかし、そのように渡そうとすると…</p>

function Ctrl2($scope, Ctrl1) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

エラーが発生します。誰もこれを行う方法を知っていますか?

やっている

Ctrl2.prototype = new Ctrl1();

また、失敗します。

注:これらのコントローラーは相互にネストされていません。

4

16 に答える 16

508

複数のコントローラー間で変数を共有する 1 つの方法は、サービスを作成し、それを使用する任意のコントローラーに挿入することです。

簡単なサービスの例:

angular.module('myApp', [])
    .service('sharedProperties', function () {
        var property = 'First';

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });

コントローラーでサービスを使用する:

function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}

これは、このブログ(特にレッスン 2 以降) で非常にうまく説明されています。

これらのプロパティに複数のコントローラー間でバインドする場合は、バインドされた参照を保持するために、プリミティブ型 (ブール値、文字列、数値) ではなくオブジェクトのプロパティにバインドするとうまくいくことがわかりました。

例:var property = { Property1: 'First' };の代わりにvar property = 'First';.


更新: (願わくば) ここで物事をより明確にするために、次の例を示すフィドルがあります:

  • 共有値の静的コピーへのバインド (myController1 内)
    • プリミティブ (文字列) へのバインド
    • オブジェクトのプロパティへのバインド (スコープ変数に保存)
  • 値が更新されると UI を更新する共有値へのバインディング (myController2 内)
    • プリミティブ (文字列) を返す関数へのバインド
    • オブジェクトのプロパティへのバインド
    • オブジェクトのプロパティへの双方向バインディング
于 2012-08-17T16:17:16.747 に答える
45

簡単な例で簡単なことを説明するのが好きです:)

非常に簡単なService例を次に示します。


angular.module('toDo',[])

.service('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  this.dataObj = _dataObj;
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

そして、ここでjsbin

そして、ここに非常に簡単なFactory例があります:


angular.module('toDo',[])

.factory('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  return {
    dataObj: _dataObj
  };
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

そして、ここでjsbin


それが単純すぎる場合は、より洗練された例を次に示します

関連するベスト プラクティスのコメントについては、こちらの回答も参照してください。

于 2014-08-09T17:34:17.507 に答える
17

$rootScope を使用して、サービスを作成しないソリューション:

アプリ コントローラー間でプロパティを共有するには、Angular $rootScope を使用できます。これはデータを共有するためのもう 1 つのオプションであり、人々がそれについて知ることができるようにします。

コントローラー間でいくつかの機能を共有するための推奨される方法はサービスです。グローバル プロパティを読み取ったり変更したりするには、$rootscope を使用できます。

var app = angular.module('mymodule',[]);
app.controller('Ctrl1', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = true;
}]);

app.controller('Ctrl2', ['$scope','$rootScope',
  function($scope, $rootScope) {
    $rootScope.showBanner = false;
}]);

テンプレートで $rootScope を使用する ($root でプロパティにアクセスする):

<div ng-controller="Ctrl1">
    <div class="banner" ng-show="$root.showBanner"> </div>
</div>
于 2014-08-27T18:58:31.953 に答える
9

上記のサンプルは魅力的に機能しました。複数の値を管理する必要がある場合に備えて、変更を加えました。これが役立つことを願っています!

app.service('sharedProperties', function () {

    var hashtable = {};

    return {
        setValue: function (key, value) {
            hashtable[key] = value;
        },
        getValue: function (key) {
            return hashtable[key];
        }
    }
});
于 2014-07-15T16:35:38.507 に答える
6

私は価値観を使用する傾向があり、なぜこれが悪い考えなのか誰でも喜んで議論します..

var myApp = angular.module('myApp', []);

myApp.value('sharedProperties', {}); //set to empty object - 

次に、サービスごとに値を挿入します。

ctrl1 で設定:

myApp.controller('ctrl1', function DemoController(sharedProperties) {
  sharedProperties.carModel = "Galaxy";
  sharedProperties.carMake = "Ford";
});

そしてctrl2からアクセス:

myApp.controller('ctrl2', function DemoController(sharedProperties) {
  this.car = sharedProperties.carModel + sharedProperties.carMake; 

});
于 2016-02-16T16:37:19.267 に答える
5

次の例は、兄弟コントローラー間変数を渡し、値が変更されたときにアクションを実行する方法を示しています。

使用例: 別のビューのコンテンツを変更するフィルターがサイドバーにあるとします。

angular.module('myApp', [])

  .factory('MyService', function() {

    // private
    var value = 0;

    // public
    return {
      
      getValue: function() {
        return value;
      },
      
      setValue: function(val) {
        value = val;
      }
      
    };
  })
  
  .controller('Ctrl1', function($scope, $rootScope, MyService) {

    $scope.update = function() {
      MyService.setValue($scope.value);
      $rootScope.$broadcast('increment-value-event');
    };
  })
  
  .controller('Ctrl2', function($scope, MyService) {

    $scope.value = MyService.getValue();

    $scope.$on('increment-value-event', function() {    
      $scope.value = MyService.getValue();
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  
  <h3>Controller 1 Scope</h3>
  <div ng-controller="Ctrl1">
    <input type="text" ng-model="value"/>
    <button ng-click="update()">Update</button>
  </div>
  
  <hr>
  
  <h3>Controller 2 Scope</h3>
  <div ng-controller="Ctrl2">
    Value: {{ value }}
  </div>  

</div>

于 2016-03-24T02:10:08.110 に答える
2

プロパティをスコープの親の一部にすることもできませんか?

$scope.$parent.property = somevalue;

私はそれが正しいとは言いませんが、うまくいきます。

于 2014-05-15T00:19:35.510 に答える
2

2 番目のアプローチ:

angular.module('myApp', [])
  .controller('Ctrl1', ['$scope',
    function($scope) {

    $scope.prop1 = "First";

    $scope.clickFunction = function() {
      $scope.$broadcast('update_Ctrl2_controller', $scope.prop1);
    };
   }
])
.controller('Ctrl2', ['$scope',
    function($scope) {
      $scope.prop2 = "Second";

        $scope.$on("update_Ctrl2_controller", function(event, prop) {
        $scope.prop = prop;

        $scope.both = prop + $scope.prop2; 
    });
  }
])

HTML :

<div ng-controller="Ctrl2">
  <p>{{both}}</p>
</div>

<button ng-click="clickFunction()">Click</button>

詳細については、plunker を参照してください。

http://plnkr.co/edit/cKVsPcfs1A1Wwlud2jtO?p=preview

于 2016-03-08T14:18:45.823 に答える
2

これを行うには2つの方法があります

1) get/set サービスを使用する

2) $scope.$emit('key', {data: value}); //to set the value

 $rootScope.$on('key', function (event, data) {}); // to get the value
于 2015-11-24T14:23:39.570 に答える
2

ああ、別の代替手段として、この新しいものを少し持ってください。これは localstorage であり、angular が動作する場所で動作します。どういたしまして。(でも、本当に、その人に感謝します)

https://github.com/gsklee/ngStorage

デフォルトを定義します。

$scope.$storage = $localStorage.$default({
    prop1: 'First',
    prop2: 'Second'
});

値にアクセスします。

$scope.prop1 = $localStorage.prop1;
$scope.prop2 = $localStorage.prop2;

値を保存する

$localStorage.prop1 = $scope.prop1;
$localStorage.prop2 = $scope.prop2;

アプリに ngStorage を注入し、コントローラーに $localStorage を注入することを忘れないでください。

于 2014-09-10T11:03:03.760 に答える
0

サービスを提供したくない場合は、このようにすることができます。

var scope = angular.element("#another ctrl scope element id.").scope();
scope.plean_assign = some_value;
于 2013-03-01T11:12:35.683 に答える
-1

$rootScope とサービスのほかに、angular を拡張して共有データを追加するためのクリーンで簡単な代替ソリューションがあります。

コントローラーで:

angular.sharedProperties = angular.sharedProperties 
    || angular.extend(the-properties-objects);

このプロパティは、スコープから分離された「角度」オブジェクトに属し、スコープとサービスで共有できます。

オブジェクトを注入する必要がないという 1 つの利点: オブジェクトは、定義後すぐにどこからでもアクセスできます!

于 2015-07-13T17:00:56.613 に答える