如何在此处重新调整我的指令以在 2 个不同的范围内工作?

How to repurpose my directive here to work in 2 different scopes?

http://plnkr.co/edit/39FGMocKB5GtQWnI1TFw?p=preview

我有 sidebar,其中包含标签列表,当您单击标签时,我使用 TagDetailsFactory 将标签发送到 [= 的范围内36=]视图控制器。

除了将鼠标悬停在 TagDetailsFactory 范围内的标记上之外,一切都很好。

tagDetails 模板不会显示,但是如果您将鼠标悬停在侧边栏范围内的同一标签上,tagDetails 会在两者中显示。这是错误的。

将鼠标悬停在边栏中的标签上应该只显示该标签的标签详细信息,以及视图范围内的标签的详细信息。


将鼠标悬停在视图范围内的标签上,不显示其详细信息


将鼠标悬停在侧边栏范围内的标签上,应该只显示其标签的详细信息,而不是视图范围内的标签,就像这里所做的那样:


步骤:
- 第一个标签数组在 cnt 控制器中 - 当您点击标签时,它会存储在 TagDetailsFactory 服务中 - 然后我向视图控制器广播一个事件,然后调用 TagDetailsFactory 中的 getTagDetails 函数来检索保存的标签并将它们存储到视图控制器中的 viewTags 数组中。


// Code goes here

angular.module('app', [])

.directive('tagDetails', function() {
    return {
    restrict: "E",
    link: function($scope, el, attrs) {
      // console.debug($scope, attrs);
    },
    scope:{
        tag:'='
    },
    template: '<div ng-show="tag.showDetails">{{tag.details}}</div>'
  };
})

.factory('TagDetailsFactory', function() {

        var savedTags = [];

        var saveTagDetails = function(tag) {
          savedTags.push(tag);
        }

        var getTagDetails = function() {
          return savedTags;
        }

        return {
            saveTagDetails : saveTagDetails,
            getTagDetails  : getTagDetails
        };
})

.controller('sidebar', function($scope,
                             $rootScope,
                             TagDetailsFactory) {
  $scope.tags = [];

  for(var i = 0; i < 10; i++) {
    $scope.tags.push(
      { name: 'Foo Bar ' + i, details: 'Details' + i }
    );
  }

  $scope.showTagDetails = function(t) {
    t.showDetails = true;
  }

  $scope.leaveTag = function(t) {
    t.showDetails = false;
  }

  $scope.sendTag = function(t) {
    TagDetailsFactory.saveTagDetails(t);
    $rootScope.$broadcast('updateView'); 
  }

})

.controller('view', function($scope,
                              $rootScope,
                              TagDetailsFactory) {

  $scope.viewTags = [];

  $scope.$on('updateView', function() {
    $scope.viewTags = TagDetailsFactory.getTagDetails();
  });

  $scope.showTagDetails = function(v) {
    v.showDetails = true;
  }

  $scope.leaveTag = function(v) {
    v.showDetails = false;
  }

});

我必须在这里创建第二个指令吗?成为视图范围内标签详细信息的模板?或者我当前的 tagDetails 指令可以以某种方式以 Angular 的方式重新调整用途吗?

我将你的 Plunker 与一个工作副本进行了分叉,我将解释我所做的更改。

这里的代码有两个问题。第一个是一个简单的拼写错误,导致您的 header 没有为鼠标悬停引用正确的函数。您的函数正在调用 showTagDetailsView(v)leaveTagView(v),但它们在控制器上被命名为 showTagDetailsleaveTag

第二个问题是将项目添加到 savedTags[] 的方式。在 JavaScript 中,object 是通过引用传递的。当您调用 savedTags.push(tag); 时,您正在将对同一 object 的引用推送到新数组中。对一个数组中的 object 所做的任何更改都将反映在另一个数组中。

相反,您想要的是 savedTags[] 中 object 的单独副本。这可以通过使用 angular.copy 来完成。请注意,我在制作副本之前还重置了 tag.showDetails = false;,否则新副本会将其设置为 true,即使您在单击时将鼠标悬停在其他元素上,详细信息也会在副本出现时立即显示它。

var saveTagDetails = function(tag) {
    tag.showDetails = false;
    savedTags.push(angular.copy(tag));
}

附带说明一下,您可能还对此处的 CSS 有疑问,因为悬停似乎会改变列表的位置,并且在某些情况下,悬停实际上会导致标签自行移出悬停,造成弹跳效果。