Я изо всех сил стараюсь придумать правильную Угловую идиому, и я почувствовал, что путь, по которому я спускаюсь, не чист. Чтобы сформировать мой сценарий с надуманным примером:Как обрабатывать события между несколькими директивами и контроллером?
- Рассмотрите Угловой контроллер, который называется
AlbumController
. AlbumController
имеет свойство объем, который является массивом объектов альбома:$scope.albums = [ { title : "Album 1", artist : "Artist 1" }, ... ]
Я использую
ng-repeat
спаренный с пользовательской директивы макет альбомы:<div ng-repeat="album in albumns"> <div fresh-album album="album"></div> </div>
И шаблон директивы устанавливает свойство для этого объекта альбома:
module.directive('freshAlbum', function() { return { template : '<button ng-click="album.selected = !album.selected">Click</button>', scope : { album = '=' }, ... }; });
Примечание. Причиной добавления атрибута
selected
является то, что при щелчке альбома выбираются пользовательские стили для указания альбома, который добавляется к элементу.- Что я хотел бы сделать: когда выбран альбом, deselect другой выбранный альбом (например, если выбран альбом 1, и пользователь выбирает альбом 2, мне нужен альбом 1 для снятия выделения).
Моя первая мысль этого была иметь $watch
в AlbumController
следить за изменениями альбома:
var selectedAlbum = -1; // Keeping track of the currently selected album
$scope.$watch('albums', function(newValue) {
angular.forEach($scope.albums, function(album, i) {
if (selectedAlbum === -1 && album.selected) {
selectedAlbum = i; // No previously selected albums
} else if (selectedAlbum === i && album.selected) {
album.selected = false; // Previously selected album; deselect it
} else if (album.selected) {
selectedAlbum = i; // Newly selected album
}
});
});
Однако, поскольку я «де-выбрав пункт» альбомы в $watch
обратного вызова, это вызывает другой $watch
, отменяя тем самым новый выбранный альбом. В этот момент я остановился, потому что чувствовал, что приближаюсь к этому.
Альтернативная идея, которую я имел, заключалась в том, чтобы директива freshAlbum
опубликовала событие «выбора», на которое реагирует контроллер. Является ли подход, как этот более угловатыми-эск "?
Я хотел бы добавить эту функцию в качестве второго параметра директивы, чтобы сделать его умным. –
T ypically, когда я делаю что-то подобное, я просто делаю все в этом методе: 'ng-click = 'select (album)' Так что один метод в основном отменяет выбор всех альбомов, а затем устанавливает правильный для выбранного. – threeve
Вы правы; лучше написать функцию в объявлении директивы, а не записывать ее как встроенную функцию в свой шаблон. – cubbuk