AngularJS: установка переменной в области с расширением ng-repeat

Как мне получить доступ к набору областей, сгенерированных ng-repeat?

Я полагаю, что в основе этого лежит тот факт, что я не совсем понимаю, как отношения работают между a) коллекцией объектов, которые я передаю в директиву ng-repeat, и b) набором областей, которые он генерирует, Я могу поиграть с (a), который просматривает и захватывает область ng-repeat, но как установить переменные в самой области (b)?

Мой вариант использования состоит в том, что у меня есть набор элементов, повторяющихся с помощью ng-repeat, каждый из которых имеет вид редактирования, который переключается с помощью ng-show/ng-hide; состояние для каждого элемента хранится в переменной в локальной области. Я хочу, чтобы иметь возможность вызвать ng-show для определенного элемента, но я хочу, чтобы триггер вызывался из вне ng-repeat, поэтому мне нужно иметь доступ к локальной переменной области видимости.

Может ли кто-нибудь указать мне в правильном направлении (или сказать мне, если я лаю неправильное дерево)?

Спасибо

Обновление: Ссылка ниже была очень благодарна. В конце я создал директиву для каждого из повторяющихся элементов и использовал функцию директивной ссылки, чтобы добавить ее область в коллекцию в области корня.

Ответы

Ответ 1

При работе в иерархии областей я считаю очень полезным отправлять события с помощью $emit и $broadcast. $ emit отправляет событие вверх, поэтому ваши дочерние области могут уведомлять родительские области определенного события. $ broadcast - это наоборот.

В качестве альтернативы, поскольку дочерние области имеют доступ к свойствам родительской области, вы можете инициировать изменения, используя $watch для определенного свойства в родительской области.

ОБНОВЛЕНИЕ: Что касается доступа к дочерним областям, это может оказаться полезным для вас: Получить все дочерние области в Angularjs с учетом родительской области

Ответ 2

Вот довольно простой способ сделать то, что, как я думаю, вы пытаетесь сделать (я понял это, когда мне нужно было сделать что-то подобное):

Мы знаем, что каждый повторный элемент имеет свою собственную область, созданную для него. Если мы сможем передать эту область методу, определенному в родительской области, то мы сможем сделать то, что хотим с ней, с точки зрения манипулирования или добавления свойств. Оказывается, это можно сделать, передав 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.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

Ответ 3

Ben Nadel дал довольно чистое решение "как мне назначить проблему ngRepeat $scope", которую я только что реализовал в своем собственном проекте. По существу, вы можете добавить директиву ngController рядом с вашим ngRepeat и манипулировать ngRepeat $scope внутри контроллера.

Ниже приведен мой собственный надуманный пример, который демонстрирует назначение ngRepeat $scope в контроллере. Да, есть лучшие способы сделать это точно. См. сообщение Бен Надела для лучшего примера.

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

РЕДАКТИРОВАТЬ: Перечитав свой вопрос, увидев, что вам нужно манипулировать связкой дочерних областей в родительской области, я считаю, что ваш подход (директивы) - это путь. Я все еще думаю, что этот ответ может быть полезен для некоторых, поскольку я наткнулся на ваш вопрос, ища этот ответ.