112

次のコントローラーがある場合:

function parent($scope, service) {
    $scope.a = 'foo';

    $scope.save = function() {
        service.save({
            a:  $scope.a,
            b:  $scope.b
        });
    }
}

function child($scope) {
    $scope.b = 'bar';
}

parentから読み取らせる適切な方法は何bですかchild? binで定義する必要がある場合、それが ではなくに関連する何かを記述するプロパティであるとparent仮定すると、意味的に正しくないのではないでしょうか?bchildparent

更新:さらに考えてみると、複数の子が持っていると、取得bする競合が発生parentします。からbアクセスする適切な方法は何ですか?bparent

4

6 に答える 6

163

AngularJSのスコープはプロトタイプの継承を使用します。子スコープでプロパティを検索する場合、インタープリターは子から開始してプロトタイプチェーンを検索し、プロパティが見つかるまで親に続きます。その逆ではありません。

この問題に関するVojtaのコメントを確認してくださいhttps://groups.google.com/d/msg/angular/LDNz_TQQiNE/ygYrSvdI0A0J

簡単に言うと、親スコープから子スコープにアクセスすることはできません。

あなたの解決策:

  1. 親でプロパティを定義し、子からそれらにアクセスします(上記のリンクを読んでください)
  2. サービスを使用して状態を共有する
  3. イベントを介してデータを渡します。$emitルートスコープまでイベントを親に上向きに送信し、$broadcastイベントを下向きにディスパッチします。これは、意味的に正しい状態を維持するのに役立つ場合があります。
于 2012-11-17T06:11:37.213 に答える
83

jm- の回答がこのケースを処理する最良の方法ですが、将来の参考のために、スコープの $$childHead、$$childTail、$$nextSibling、および $$prevSibling メンバーを使用して子スコープにアクセスすることができます。これらは文書化されていないため、予告なしに変更される可能性がありますが、本当にスコープをトラバースする必要がある場合はそこにあります。

// get $$childHead first and then iterate that scope's $$nextSiblings
for(var cs = scope.$$childHead; cs; cs = cs.$$nextSibling) {
    // cs is child scope
}

フィドル

于 2013-05-31T09:00:48.583 に答える
4

考えられる回避策の 1 つは、init 関数を使用して親コントローラーに子コントローラーを挿入することです。

可能な実装:

<div ng-controller="ParentController as parentCtrl">
   ...

    <div ng-controller="ChildController as childCtrl" 
         ng-init="ChildCtrl.init()">
       ...
    </div>
</div>

あなたが持っている場所ChildController

app.controller('ChildController',
    ['$scope', '$rootScope', function ($scope, $rootScope) {
    this.init = function() {
         $scope.parentCtrl.childCtrl = $scope.childCtrl;
         $scope.childCtrl.test = 'aaaa';
    };

}])

だから今ParentControllerあなたは使用することができます:

app.controller('ParentController',
    ['$scope', '$rootScope', 'service', function ($scope, $rootScope, service) {

    this.save = function() {
        service.save({
            a:  $scope.parentCtrl.ChildCtrl.test
        });
     };

}])

重要:
正しく動作させるには、ディレクティブを使用し、html で行ったようにng-controller各コントローラーの名前を変更する必要があります。as

ヒント:
プロセス中に chrome プラグインng-inspectorを使用します。木を理解するのに役立ちます。

于 2015-07-03T03:26:04.677 に答える