使用自定义指令时,ngShow无法正常工作

时间:2014-05-07 10:49:58

标签: javascript angularjs javascript-events angularjs-directive

我有角度的代码:

<span ng-mouseover="item.show_description=true" ng-mouseleave="item.show_description=false" pointer="{x: item.x, y: item.y}">
    {{item.label}}
</span>
<div class="description-popup" ng-show="!!item.description && item.show_description"
     style="left: {{item.x}}px; top: {{item.y}}px">
    <h2>{{item.label}}</h2>
    <p>{{item.description}}</p>
    <p>{{!!item.description && item.show_description}}</p>
</div>

它正确显示弹出窗口,但如果descritpion为null或空字符串,弹出窗口仍会显示。该案例中的最后一个表达式显示为false。我在这里做错了什么?或者也许那里有一个bug。我正在使用Angular 1.0.6(现在无法升级)。

更新

我已经创建了 JSFiddle ,看来ng-show按预期工作,但是当我使用指针指令时,使用mousemove事件。该指令的代码如下:

app.directive('pointer', function($parse) {
    function objectParser(expr) {
        var strip = expr.replace(/\s*\{\s*|\s*\}\s*/g, '');
        var pairs = strip.split(/\s*,\s*/);
        if (pairs.length) {
            var getters = {};
            var tmp;
            for (var i=pairs.length; i--;) {
                tmp = pairs[i].split(/\s*:\s*/);
                if (tmp.length != 2) {
                    throw new Error(expr + " is Invalid Object");
                }
                getters[tmp[0]] = $parse(tmp[1]);
            }
            return {
                assign: function(context, object) {
                    for (var key in object) {
                        if (object.hasOwnProperty(key)) {
                            if (getters[key]) {
                                getters[key].assign(context, object[key]);
                            }
                        }
                    }
                }
            }
        }
    }



    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var expr = objectParser(attrs.pointer);
            element.mousemove(function(e) {
                var offest = element.offset();
                scope.$apply(function() {
                    expr.assign(scope, {
                        x: e.pageX - offest.left,
                        y: e.pageY - offest.top
                    });
                });
            });
        }
    };

});

1 个答案:

答案 0 :(得分:3)

隔离范围

问题是ng-show使用了它所在元素的范围。如果它在具有带隔离范围的指令的元素上,那么它将使用该隔离范围,而不能访问外部范围。

在这种特殊情况下,我怀疑description-popup具有隔离范围,这意味着ng-show只能访问该指令的范围,该范围可能没有item你试图反对。

什么是隔离范围?

隔离范围意味着该指令具有自己的范围,不会从周围范围继承。正常范围继承自周围的范围,因此可以访问该周围范围的数据。隔离范围没有。

为什么有人想要使用隔离范围?!

复用。如果一个指令打算在许多地方重复使用,在许多不同的范围内具有各种属性,你就不希望指令范围内的属性与周围的属性发生冲突。范围。并且由于该指令应该是完全独立的并且根本不使用周围的范围,因此给它一个隔离范围通常是一个好主意。这方面的缺点很少。实际上,唯一可能出错的是当有人想在该元素上添加ng-showng-hide时。

<强>解决方案

ng-show放在<div>附近的额外description-popup上:

<div ng-show="!!item.description && item.show_description">
    <div class="description-popup"
         style="left: {{item.x}}px; top: {{item.y}}px">
        <h2>{{item.label}}</h2>
        <p>{{item.description}}</p>
        <p>{{!!item.description && item.show_description}}</p>
    </div>
</div>

这假设此JSFiddle中的行为符合您的要求。

这可能只适用于Angular&lt; 1.2。在1.2中,隔离范围的行为似乎已被清除:https://docs.angularjs.org/guide/migration#isolate-scope-only-exposed-to-directives-with-scope-property