如何处理多个指令和控制器之间的事件?

时间:2014-10-09 13:11:16

标签: javascript angularjs

我正在努力想出适当的Angular成语,我觉得我走的路是非纯粹的。用一个人为的例子构建我的场景:

  • 考虑一个名为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属性的原因是,当点击相册时,会选择用于指示相册的自定义样式。

  • 我想要做的是:当选择一个专辑时,取消选择其他所选专辑(例如,如果选择了专辑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指令发布控制器响应的“选择”事件。像这样的方法更像Angular-esque“?

1 个答案:

答案 0 :(得分:2)

您可以向指令添加表达式,只要单击相册就会调用该表达式。

module.directive('freshAlbum', function() {   return {
    template : '<button ng-click="album.selected = !album.selected; albumIsClickedEvent();">Click</button>',
    scope : { album : '=' 
              albumIsClicked: "&"},
    ...   }; });

<div ng-repeat="album in albumns">
  <div fresh-album album="album" album-is-clicked="albumIsClickedEvent"></div>
</div>

在您的控制器中,您可以实现albumIsClickedEvent功能来完成您想要实现的功能(关闭其他打开的专辑等)。

通过这个表达式指令可以与外部控制器通信。