ng节目需要'双重评估'
ng-show needs to 'double evaluate'
摘要
对于ng-show
,我想使用一个需要首先求值的对象属性。
示例
我有一个包含lanOption
(语言)对象的数组,我想将其显示在select
元素中。是否显示语言取决于作用域中的变量couID
(country)。
我想通过一个额外的属性在对象中包含关于显示或隐藏语言的逻辑,然后由ng-show
使用,如下所示:
模型
$scope.lanOptions = [
{name: "English", ngShow: "1"},
{name: "Danish", ngShow: "$scope.couID='DK'"},
{name: "French", ngShow: "$scope.couID='FR' || $scope.couID='BE'"},
{name: "Dutch", ngShow: "$scope.couID='NL' || $scope.couID='BE'"}
]
(应始终显示英语,仅当选择丹麦时显示丹麦语,等等)
视图
<select>
<option ng-repeat="o in lanOptions" ng-show="{{o.ngShow}}" value="{{o.name}}">{{o.name}}</option>
</select>
问题
这里的重要部分是ng-show
属性——有办法让它发挥作用吗?和/或有没有更好的方式让我错过?我试过filter:
,但没有成功。
谢谢!
编辑
为了澄清:这个例子实际上被简化为我实际想要做的事情。在我的实际问题中,有更多的变量值可能会影响每个选项的可见性。
例如,考虑
{name: 'Basque', ngShow: "($scope.couID=='ES' || $scope.couID=='FR') && $scope.inclMinority==true"}
或
{name: 'German', ngShow: "$scope.couID=='DE' ||
$scope.couID=='AU' ||
($scope.couID=='BE' && $scope.inclMinority==true)"}
,或更复杂的表达式。
这就是为什么我没有将couID
数组作为属性添加到每个语言对象中——如果我之前没有明确提到这一点,我很抱歉。
用$scope.
修复模型@ngShow: "$scope.couID='DK'"}
中的作用域变量名不是一个好主意。如果您计划更改包含作用域的变量名,或者将此模型移植到某个地方,它将变得不可用。属性名称$scope.couID
的条件检查也是如此(也许您添加了它作为一种灵活性,这样您就可以针对couID
等作用域和各种不同的条件放置要针对多个变量评估的筛选条件)。然而,即使在绑定ngShow
中的ngShow条件表达式中使用插值,也不会得到求值结果(可能还会出现语法错误)。
对ng-show使用插值也不是一个好主意,因为它会寻找即使是字符串"false"
也是真实的表达式(这就是它的计算结果,如果你在布尔值上使用ng-show进行插值,那么不管你的情况如何,你都有默认情况下不起作用的条件),你最终会始终显示所有选项。
您应该停止重复使用ng来创建select,而是开始使用ng选项
一种方法是,通过在模型中保留条件,您可以在使用$parse获取项本身的同时评估ng-show表达式,为什么要为ng-show
添加不需要的监视?:-
在控制器中注入$parse
,以便根据作用域解析表达式:-
.controller('MainCtrl', function($scope, $parse) {
//.....
//In your method just return only necessary dropdown values
$scope.getLanOptionsForCountry = function(){
//Just filter it based on selected country and populate the select.
return $scope.lanOptions.filter(function(itm){
return $parse(itm.ngShow)($scope);
});
}
//...
您的选择看起来就像:-
<!-- Just added for the demo to select a country -->
<select ng-model="couID" ng-options = "country.code as country.name for country in countries">
<option value="">--Choose one--</option>
</select>
<!-- This will be your selected, just added a placeholder option as well and an ngModel -->
<select ng-model="language" ng-options = "lang.name for lang in getLanOptionsForCountry()">
<option value="">--Choose one--</option>
</select>
Plnkr-演示
或者,您甚至可以通过消除视图模型中的条件,并为仅显示这些选项的国家/地区代码放置一个过滤器,使视图模型更具可移植性。
//Add a filter property which if present will display only for those country code else if will always display
$scope.lanOptions = [
{name: "English"},
{name: "Danish", filter: ["DK"]},
{name: "French", filter: ["FR", "BE"]},
{name: "Dutch", filter:["NL", "BE"]}
];
$scope.getLanOptionsForCountry = function(){
return $scope.lanOptions.filter(function(itm){
return !itm.filter || (itm.filter.indexOf($scope.couID) + 1);
});
}
Plnkr2-演示
请参阅polyfill和对Array.Filter的支持
我会将您的语言选项更改为
$scope.lanOptions = [
{name: "English", countries: ["EN"]},
{name: "Danish", countries: ["DK"]},
{name: "French", countries: ["FR","BE"]},
{name: "Dutch", countries: ["NL","BE"]}
]
将ng显示更改为作用域上的函数调用:
ng-show="showCountry(o)"
范围:
$scope.showCountry = function (lanOption) {
return (lanOption.countries.indexOf("EN")> -1
||lanOption.countries.indexOf($scope.couID)>-1)
}
编辑:实际上,在进一步考虑这一点后,您可以一起取消ng show,并用对一个函数的调用来代替ng repeat,该函数只需返回您需要的项目:
$scope.getLanOptionsForCountry = function () {
return @scope.lanOptions.filter( function( item) {
return item.countries.indexOf("EN")>-1 ||
item.countries.indexOf($scope.couID)
});
}
然后
<select>
<option ng-repeat="o in getLanOptionsForCountry()" value="{{o.name}}">{{o.name}}</option>
</select>
- 使用正则表达式评估电子邮件地址时出现性能问题
- 如何检查链接是否有文本,并根据文本值评估条件-Jquery/JS
- 类型错误'未定义'不是对象(正在评估'navigator.connection.type'
- 下载javascript文件,但不要立即对其进行评估
- 为什么ng节目不起作用
- 在WebView iOS中评估Javascript
- TypeError:undefined不是对象(正在评估'newWindow.focus')
- r.js评估'text'插件,尽管在'stubModules'参数
- 避免重新评估和动态卸载用“require”调用的对象
- 删除评估值Javascript时的错误
- 咖啡脚本意外的条件评估
- Javascript-在一行中评估多个正则表达式
- &&评估问题
- 在JavaScript中评估复杂的数学表达式
- JavaScript:获取对象的评估属性
- 基本的Javascript/jQuery数学游戏:为什么可以't我第二次运行此函数时进行评估
- 带有 Sweet.js 的惰性评估宏
- 蒙戈 --安静不抑制 --评估输出
- Momentjs节目少评估一天
- ng节目需要'双重评估'