23

我有一个这样使用的指令:

<dir model="data"></dir>

该指令有一个孤立的范围。

scope :{
  model:'='
}

现在我正在尝试使用ng-show我的页面 $scope 的另一个属性来使用该指令,如下所示:

<dir ng-show="show" model="data"></dir>

但它不起作用,因为指令试图show在自己的范围内找到属性。

我不希望指令知道它的容器可能选择隐藏它的事实。

我发现的解决方法是将指令包装在 a 中<div>并应用于ng-show该元素,但我不喜欢这迫使我使用的额外元素:

<div ng-show="show" >
  <dir model="data"></dir>    
</div>

有没有更好的方法来做到这一点?

看到这个 plunker:http ://plnkr.co/edit/Q3MkWfl5mHssUeh3zXiR?p=preview

4

4 回答 4

12

更新:此答案适用于 1.2 之前的 Angular 版本。请参阅@lex82 对 Angular 1.2 的回答。

因为您的dir指令创建了一个隔离范围,所以在同一元素上定义的所有指令(dir在这种情况下)都将使用该隔离范围。这就是为什么在隔离范围而不是父范围上ng-show查找属性的原因。show

如果您的dir指令确实是一个独立/自包含/可重用的组件,因此它应该使用隔离范围,那么您的包装解决方案可能是最好的(比使用$parent,IMO 更好),因为此类指令通常不应与其他指令一起使用相同的元素(或者你会遇到这种问题)。

如果您的指令不需要隔离范围,那么您的问题就会消失。

于 2013-05-25T14:16:22.670 回答
11

您可以考虑迁移到 Angular 1.2 或更高版本。隔离作用域现在只暴露给具有作用域属性的指令。这意味着 ng-show 不再受您的指令影响,您可以像一开始那样编写它:

<dir ng-show="show" model="data"></dir>

@Angular-Developers:干得好,伙计们!

于 2013-11-17T18:17:17.697 回答
4

将以下内容添加到链接功能中可以解决问题。对于组件创建者来说,这是一个额外的步骤,但使组件更加直观。

function link($scope, $element, attr, ctrl) {

    if (attr.hasOwnProperty("ngShow")) {
        function ngShow() {
            if ($scope.ngShow === true) {
                $element.show();
            }
            else if($scope.ngShow === false) {
                $element.hide();
            }
        }
        $scope.$watch("ngShow", ngShow);
        setTimeout(ngShow, 0);
    }
    //... more in the link function
}

您还需要为 ngShow 设置范围绑定

scope: {
    ngShow: "="
}
于 2013-09-10T15:30:16.087 回答
1

只需$parent像这样用于父范围:

<dir ng-show="$parent.show" model="data"></dir>

免责声明

我认为这是对您问题的准确答案,但我承认从美学的角度来看它并不完美。但是,包裹起来<div>也不是很好。我认为可以证明这一点,因为从传递给隔离范围的另一个参数可以看出,该指令实际上具有隔离范围。另一方面,我必须承认我经常忘记 $parent 首先然后想知道为什么它不起作用。

添加一个附加属性并在内部is-visible="expression"插入肯定会更清楚。ng-show但是你在你的问题中说你试图避免这个解决方案。

更新: 不适用于 Angular 1.2 或更高版本。

于 2013-11-12T22:10:17.080 回答