将ngIf
优先级(600)设置为高于{{ }}
(100)的原因是什么?它的优先级是否不足以在{{ }}
属性值中ng-if
允许?
我想在$scope
变量中包含一个条件:
控制器:
app.controller('MainCtrl', function($scope, $http, $parse) {
$scope.hide = "check === 'hidden'";
$scope.parsecond = function (cond) {
return $parse(cond)($scope);
};
});
模板:
<body ng-controller="MainCtrl">
<div ng-if="!{{hide}}">funky ng-if div</div>
<div ng-hide="{{hide}}">ng-hide div</div>
<div ng-if="!parsecond(hide)">ng-if div</div>
<input type="input" ng-model="check" />
</body>
ng-hide
工作正常,因为它解析了hide变量的内容并返回&#34; check ===&#39; hidden&#39;&#34;然后由ng-hide
指令进行评估。
但ng-if
尝试在插值有机会解析字符串之前评估{{hide}}
,因此ng-if
会抛出异常。
我发现的唯一解决方案是调用一个基本上完成interpolate指令工作并返回解析内容的函数。
Plnkr显示问题:link
修改
阅读完文档后,我发现更好的方法是在$scope
上不需要自定义方法,因为angularjs已经有一个方法可以根据当前$scope
解析变量( $eval
)。
所以我的解决方案是:
<body ng-controller="MainCtrl">
<div ng-if="!$eval(hide)">funky ng-if div</div>
<div ng-hide="{{hide}}">ng-hide div</div>
<div ng-if="!parsecond(hide)">ng-if div</div>
<input type="input" ng-model="check" />
</body>
更新了plnkr:link
虽然这仍然无法解释为什么ngIf具有更高的优先级。
编辑2:
只是让人们明白它不一样:
例如:
控制器:
$scope.value = "hi";
$scope.condition = "value === 'bye'";
HTML:
<div ng-hide="condition"></div> <!--This will be evaluated to true since !!"value ==='bye'" = true. -->
<div ng-hide="{{condition}}"></div> <!--This will be evaluated to false since value !== 'bye' = false -->
<div ng-if="condition"></div> <!--This will be evaluated to true since !!"value === 'bye'" = true. -->
<div ng-if="{{condition}}"></div> <!--This will give an exception since ngIf directive ran before interpolation directive in the $compile step. -->
<div ng-if="$eval(condition)"></div> <!--This will be evaluated to false since value !== 'bye' = false. -->
我的结论是,如果您希望指令在字符串中而不是在作用域上的属性中评估/设置监视,则使用$parse
会更安全。虽然我可以{{ }}
使用ng-hide
/ ng-show
或任何优先级低于100的指令,但我猜测它是正确的。不安全,因为我依赖于编译顺序,并且它不是100%明确表示它在未来的补丁中不会发生变化。
答案 0 :(得分:5)
ng-if
期望其值是一个角度表达式 - under the hood它只使用$scope.$watch
。因此,如果您想在范围内定义的某些变量(包括:ng-if
)中包含scope.hide
的内容,则将ng-if="hide"
添加到您的标记中。这里没有双花括号。
现在回到你的问题:ng-if
的优先级为600
,$interpolate
是角度服务,而不是指令。因此$interpolate
没有定义优先权。你从哪里得到100
?
您可以通过添加标记ng-if
,随时在某些功能(包括scope.conditionFn
)中包含ng-if="conditionFn()"
的内容。
我更新了您的PLNKR以使其正常运行。 您的plunker中 ng-if
和ng-hide
之间的不一致与$compile
中发生的插值优先级无关。
看起来你是正确的插值顺序在这里起作用,但是......我真的看不到在angular的表达式内插入任何好的理由。 ng-if
具有相对较高优先级的原因是它从/向DOM移除/添加了被转换的内容,而ng-hide
只显示/隐藏了被转换的内容。我认为一个指令似乎可以工作而另一个指令是一个纯粹的巧合。 但是如果你不使用不必要的,多余的技巧,按预期工作,我的plunker会显示。
答案 1 :(得分:0)
要理解它为什么这样做,请观察this sample here的控制台,其中自定义指令(类似于ngIf
)此时位于优先级0.该指令旨在删除元素,无需等待,将其添加回来。然而,您会看到一个错误,该错误是由于尝试将属性设置回transclude: element
所导致的遗留而导致的错误,在这种情况下,ngIf
只是一个标记,元素已经以评论的形式出现。
为了避免这种情况发生,ngIf
通过提高优先级terminal:true
并通过直接监控其直接从$tAttrs
抓取的表达式来提前终止该过程。插值将执行,但这是在稍后阶段完成的,通过在ngIf
表达式变为真的时刻调用转换函数,在原始元素的克隆上,现在在其控制之下。新元素将在评论元素下显示出漂亮和花花公子。
Here is the same sample but fixed。避免了错误情况。