web-dev-qa-db-ja.com

AngularJS:ng-repeatで生成されたスコープに変数を設定する

Ng-repeatによって生成されたスコープのセットにアクセスするにはどうすればよいですか?

私はこれの中心に、a)ng-repeatディレクティブに渡すオブジェクトのコレクションとb)それが生成するスコープのコレクションの間の関係がどのように機能するのかを完全に理解していないという事実があると思います。 ng-repeatスコープが監視して取得する(a)をいじることができますが、スコープ自体(b)に変数を設定するにはどうすればよいですか?

私の使用例は、ng-repeatを使用して繰り返す一連の要素があり、それぞれにng-show/ng-hideを使用して切り替えられる編集ビューがあることです。各要素の状態は、ローカルスコープの変数に保持されます。特定の要素でng-showをトリガーできるようにしたいが、トリガーがoutside ng-repeatから呼び出されるようにしたいので、ローカルスコープ変数にアクセスできる必要がある。

誰かが私を正しい方向に向けることができますか(または私が間違った木を吠えているかどうかを教えてください)?

ありがとう

更新:以下のリンクは非常に役に立ちました。最後に、繰り返し要素ごとにディレクティブを作成し、ディレクティブのリンク関数を使用して、そのスコープをルートスコープのコレクションに追加しました。

16
Steve

スコープの階層内で作業するとき、$ emitと$ broadcastを使用してイベントをディスパッチするのが非常に便利です。 $ emitはイベントを上方にディスパッチし、子スコープが親スコープに特定のイベントを通知できるようにします。 $ broadcastはその逆です。

または、子スコープが親スコープのプロパティにアクセスできるため、親スコープの特定のプロパティで$ watchを使用して変更をトリガーできます。

UPDATE:子スコープへのアクセスに関しては、これが役立つかもしれません: Getを実行して、Angularjsで親スコープを指定してすべての子スコープを取得します

1
Joe Minichino

これは、あなたがやろうとしていることを実行するための非常に単純な方法です(私が同様のことをする必要があるときにこれを理解しました)。

繰り返される各アイテムには、独自のスコープが作成されることがわかっています。このスコープを親スコープで定義されたメソッドに渡すことができれば、プロパティの操作や追加に関して、このスコープを使って必要なことを実行できます。これは、thisを引数として渡すことで実行できることがわかります。

_// collection on controller scope
$scope.myCollection = [
  { name: 'John', age: 25 },
  { name: 'Barry', age: 43 },
  { name: 'Kim', age: 26 },
  { name: 'Susan', age: 51 },
  { name: 'Fritz', age: 19 }
];



// template view
<ul>
  <li ng-repeat="person in myCollection">
    <span ng-class="{ bold : isBold }">{{ person.name }} is aged {{ person.age }} </span>
    <button class="btn btn-default btn-xs" ng-click="toggleBold(this)">toggle bold</button>
  </li>
</ul>
_

したがって、「太字の切り替え」ボタンを押すと、コントローラーの$ scopeで定義する必要がある$scope.toggleBold()メソッドを呼び出します。 thisを引数として渡すことに注意してください。これは実際には現在のng-repeat scopeオブジェクトです。

したがって、このように操作できます

_$scope.toggleBold = function(repeatScope) {
  if (repeatScope.isBold) {
    repeatScope.isBold = false;
  } else {
    repeatScope.isBold = true;
  }
};
_

これが実際の例です: http://plnkr.co/edit/Vg9ipoEP6wxG8M1kpiW3?p=preview

19
Michael Bromley

Ben Nadelかなりクリーンなソリューション を「ngRepeat$scopeに割り当てる方法」の問題に与えました。私自身のプロジェクト。基本的に、ngControllerの横にngRepeatディレクティブを追加し、コントローラー内でngRepeat$scopeを操作できます。

以下は、コントローラーでngRepeat$scopeに割り当てることを示す、私自身の不自然な例です。はい、これを正確に行うにはよりよい方法があります。より良い例は Ben Nadelの投稿 を参照してください。

<div ng-controller="ListCtrl">
  <h1>ngRepeat + ngController</h1>
  <ul>
    <li ng-repeat="item in items" ng-controller="ItemCtrl" ng-show="isVisible">
      {{item.name}}
      <button ng-click="hide()">hide me!</button>
    </li>
  </ul>
</div>

<script type="text/javascript">
  var app = angular.module("myApp", []);

  app.controller("ListCtrl", function($scope) {
    $scope.items = [
      {name: "Item 1"},
      {name: "Item 2"},
      {name: "Item 3"}
    ];
  });

  app.controller("ItemCtrl", function($scope) {
    $scope.isVisible = true;
    $scope.hide = function() {
      $scope.isVisible = false;
    };
  });
</script>

EDIT:質問をもう一度読んだ後、親スコープ内の子スコープの束を操作する必要があることがわかり、ディレクティブは)アプローチは進むべき道です。私はまだこの答えを探している間にあなたの質問に出くわしたので、この答えは一部にとって役に立つかもしれないと思います。

11
Spencer Judd