web-dev-qa-db-fra.com

AngularJS: Définition d'une variable dans une étendue générée par ng-repeat

Comment accéder à l'ensemble des étendues générées par une répétition ng?

Je suppose qu'au cœur de cela se trouve le fait que je ne comprends pas très bien comment fonctionne la relation entre a) la collection d'objets que je passe dans la directive ng-repeat et b) la collection d'étendues qu'elle génère. Je peux jouer avec (a), que l'oscilloscope ng-repeat surveille et capte, mais comment puis-je définir des variables sur l'oscilloscope lui-même (b)?

Mon cas d'utilisation est que j'ai un ensemble d'éléments se répétant à l'aide de ng-repeat, chacun ayant une vue d'édition qui est basculée à l'aide de ng-show/ng-hide; l'état de chaque élément est conservé dans une variable dans la portée locale. Je veux pouvoir déclencher un ng-show sur un élément particulier, mais je veux que le déclencheur soit appelé depuis extérieur le ng-repeat, donc je dois pouvoir accéder à la variable de portée locale .

Quelqu'un peut-il m'orienter dans la bonne direction (ou me dire si j'aboie le mauvais arbre)?

Merci

Mise à jour: Le lien ci-dessous a été très utile et reconnaissant. À la fin, j'ai créé une directive pour chacun des éléments répétitifs et j'ai utilisé la fonction de lien de la directive pour ajouter sa portée à une collection sur la portée racine.

16
Steve

Lorsque je travaille dans une hiérarchie d'étendues, je trouve très utile de distribuer des événements avec $ emit et $ broadcast. $ emit distribue un événement vers le haut afin que vos étendues enfants puissent notifier les étendues parentes d'un événement particulier. $ broadcast est l'inverse.

Comme les étendues enfants ont accès aux propriétés de l'étendue parent, vous pouvez déclencher des modifications en utilisant $ watch sur une propriété particulière de l'étendue parent.

MISE À JOUR: En ce qui concerne l'accès aux portées enfants, cela peut devenir utile pour vous: Obtenez pour obtenir toutes les portées enfants dans Angularjs étant donné la portée parent

1
Joe Minichino

Voici un moyen assez simple de faire ce que je pense que vous essayez de faire (j'ai compris cela quand j'avais besoin de faire quelque chose de similaire):

Nous savons que chaque élément répété a sa propre portée créée pour lui. Si nous pouvions transmettre cette portée à une méthode définie sur la portée parent, nous pourrions alors faire ce que nous voulons en termes de manipulation ou d'ajout de propriétés. Il s'avère que cela peut être fait en passant this comme argument:

Exemple

// 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>

Ainsi, lorsque nous appuyons sur le bouton "basculer en gras", nous appelons la méthode $scope.toggleBold() que nous devons définir sur la portée $ du contrôleur. Notez que nous passons this comme argument, qui est en fait l'objet courant ng-repeat scope.

Par conséquent, nous pouvons le manipuler comme ça

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

Voici un exemple de travail: http://plnkr.co/edit/Vg9ipoEP6wxG8M1kpiW3?p=preview

19
Michael Bromley

Ben Nadel a donné ne solution assez propre au "comment puis-je affecter à un ngRepeat's $scope ", que je viens d'implémenter dans mon propre projet. Essentiellement, vous pouvez ajouter une directive ngController à côté de votre ngRepeat, et manipuler ngRepeat's $scope à l'intérieur du contrôleur.

Ci-dessous est mon propre exemple artificiel, qui montre l'attribution à ngRepeat's $scope dans un contrôleur. Oui, il y a sont de meilleures façons de faire exactement cette chose. Voir le post de Ben Nadel pour un meilleur exemple.

<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: Après avoir relu votre question, vu que vous devez manipuler un tas de portées enfants dans une portée parent, je pense que votre directive (s ) est la voie à suivre. Je pense toujours que cette réponse peut être utile à certains, car je suis tombé sur votre question en cherchant cette réponse.

11
Spencer Judd