如何使元素指令相对于ng重复项目的位置?

时间:2015-05-11 21:26:48

标签: javascript angularjs angularjs-directive angularjs-ng-repeat

我有一个ng-repeat数组中的标记对象列表。将鼠标悬停在任何标记上时,与该标记相关的<tags-hover>元素会显示其他标记信息。

通过我的标记和代码设置方式,<tags-hover>会显示每个悬停标记的正确信息。但是,显示的<tags-hover>的位置始终是ng-repeat列表中的最后一个位置。

理想情况是,每个标记悬停的<tags-hover>会直接显示在该标记下方,而不是最后一个标记。

更新我使用scopeFactory来保存和存储我的控制器和指令的范围,看起来我可能需要一种方法来索引我需要的tagHover范围。

enter image description here &LT;我在这里悬停在第一个标签上。

我在tagPanel中的标记:

<ul>
    <li ng-repeat="(k, m) in tags | filter:filterTags | orderBy:predicate:reverse"
        ng-class="{'selected': m.selected}"
        ng-mouseover="hoverTag(m)"
        ng-mouseleave="leaveTag()"
        ng-click="selectTag(m)" class="tag-li" style="transition-delay: {{$index * 60}}ms">

        <div class="tag"
             ng-class="{'positive': m.direction == 'positive',
                        'negative': m.direction == 'negative',
                        ''        : m.direction == 'stagnant'}">
                        {{m.term}} 
        </div>

        <!-- below is that popover div with tag details -->
        <tags-hover></tags-hover>
    </li>
</ul>

tagsHover HTML标记:

<div class="tags-hover-container" ng-show="tagsHoverDisplay">
    ...

tagsHover样式:

.tags-hover-container {
    float: left;
    position: relative;
    width: 250px;
    height: auto;
    background: $gray_bg;
    border: 1px solid $gray2;
    z-index: 10000;
    @include rounded(3px);
    @include clearfix;

    &:before {
        position: absolute;
        top: -10px;
        left: 26px;
        z-index: 9999;
        @include triangle(up, 10px, $gray_bg);
    }

    &:after {
        position: absolute;
        top: -11px;
        left: 25px;
        z-index: 9998;
        @include triangle(up, 11px, $gray2);
    }
}

tagsPanel Controller:

vs.hoverTag = function(tagObj) {
    tagsHover = ScopeFactory.getScope('tagsHover');
    tagsHover.breakTimeout = true;
    TagDetailsFactory.saveTagDetails(vs.ticker, tagObj);
};

vs.leaveTag = function() {
    tagsHover.breakTimeout = false;
    tagsHover = ScopeFactory.getScope('tagsHover');
    $timeout(tagsHover.leavingTag, 500);
};

inbetween服务标签详细信息:

var saveTagDetails = function(ticker, tag) {

    ApiFactory.getTagData(ticker, tag.term_id).then(function(data) {

        // API code and data calculation stuffs...

        tag.tweet_percentage = increase;
        details.direction    = tag.direction;
        //etc etc ...

        // I get the scope of the tagsHover Directive and then call hoveringTag()
        tagsHover = ScopeFactory.getScope('tagsHover');
        tagsHover.hoveringTag();
    });
};

我的tagHover指令中的代码:

var vs                  = $scope;
    vs.breakTimeout     = false,
    vs.tagDetails       = {},
    vs.tagsHoverDisplay = false;
    ScopeFactory.saveScope('tagsHover', vs);

vs.hoveringTag = function() {
    vs.tagDetails       = {};
    vs.tagDetails       = TagDetailsFactory.getTagDetails();
    vs.tagsHoverDisplay = true;
};

vs.leavingTag = function() {
    if (vs.breakTimeout) {} else {
        vs.tagsHoverDisplay = false;
    }
};

你将如何接近修复该显示器是相对于悬停的标签?而不是ng-repeat中的最后一个?

请注意,此处是chrome dev工具的HTML屏幕截图,即使我将鼠标悬停在其他代码上,最后li中的标记悬停也会获得所有更新,我看到tweets计数只改变最后一个:

enter image description here

1 个答案:

答案 0 :(得分:1)

正如评论中所示,最可能的原因是只有一个<tags-hover>可见是ScopeFactory。

我的解决方案是在模型中看到<tags-hover>并且避免访问其他元素的范围时保留决策。

代码示例: http://plnkr.co/edit/aHUh1AX7hMyafzaCZnPI?p=preview

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

我以这种方式实现了指令,它的可见性取决于属于模型的showDetails属性。

现在我需要的是更改此属性,e.x。在控制器中

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

对应的html:

<li ng-repeat="t in tags">
  <div ng-mouseover="showTagDetails(t)">{{t.name}}</div>
  <tag-details ng-model="t"></tag-details>
</li>

showDetails不必用false初始化:如果属性不存在,它将简单地评估为假。

唯一的缺点是您需要将此属性添加到模型数据中,最终可能会覆盖其他内容。 在这种情况下,您需要将模型包装在另一个对象中。