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