如何在具有隔离范围的指令上使用ng-show

时间:2013-05-25 06:53:44

标签: angularjs

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

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

该指令具有独立的范围。

scope :{
  model:'='
}

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

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

但它没有用,因为该指令试图在自己的范围内找到show属性。

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

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

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

有更好的方法吗?

请参阅此plunker:http://plnkr.co/edit/Q3MkWfl5mHssUeh3zXiR?p=preview

4 个答案:

答案 0 :(得分:12)

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

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

如果你的dir指令真的是standalone/self-contained/reusable component,因此它应该使用隔离范围,你的包装解决方案可能是最好的(比使用$parent,IMO更好),因为这样的指令通常不应该与同一元素上的其他指令一起使用(或者你得到这种问题)。

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

答案 1 :(得分:11)

您可以考虑迁移到Angular 1.2或更高版本。 The isolate scope is now only exposed to directives with a scope property。这意味着ng-show不再受你的指令的影响,你可以像你最初尝试的那样写它:

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

@Angular-Developers:很棒的工作,伙计们!

答案 2 :(得分: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: "="
}

答案 3 :(得分:1)

只需将$parent用于父作用域,如下所示:

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

<强>声明

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

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

更新: 无法在Angular 1.2或更高版本中使用。