我尝试创建一个指令,列出错误对象({phone: ["is required"]
}中包含的所有错误,但仅当对象非空时才会列出。说"以下错误......"当没有错误时没有意义。)
通过测试Object.keys(errors).length
,我想出了如何检查对象是否为空。 问题是我无法弄清楚如何从我的指令模板中访问Object.keys。这可能吗?
因为Angular表达式被评估" (在$parse
的上下文中使用eval()
而不是scope
)而不是window
的上下文中,我们无法访问Object
之类的内容1}}来自指令模板,因为Object
不是范围的属性。 (文件:Expressions)
到目前为止有道理。它继续说"与JavaScript不同,其中名称默认为全局window
属性,Angular表达式必须显式使用$window
来引用全局window
对象。例如,如果要在表达式中调用alert()
,则必须使用$window.alert()
。
但即使我Object
,我似乎无法访问$window.Object
。我错过了什么?
这是我调试指令的代码(这里是jsfiddle):
app.js.coffee:
…
.directive 'displayErrorsAllKeys', ->
{
restrict: 'A',
scope: {
errors: '='
debug: '@debug'
}
templateUrl: 'templates/display-errors-all-keys'
}
.run(['$rootScope', ($rootScope) ->
$rootScope.nonEmpty = (object) ->
!! Object.keys(object).length
])
.controller('TestDisplayErrorsAllKeys',
['$scope',
( $scope ) ->
$scope.other_errors = {}
$scope.add_errors = ->
$scope.other_errors = {"surname":["is required"],"phone":["is required"]}
$scope.clear_errors = ->
$scope.other_errors = {}
])
显示错误 - 全keys.ngt.haml:
.errors(ng-show="$window.Object.keys(errors).length > 0")
%p The following errors prevented this from saving:
%div(ng-repeat="(key, error_messages) in errors") {{key}}: {{error_messages | toSentence}}
test_ng_display-错误 - 全keys.html.haml
:scss
.errors {
color: red;
}
%div(ng-app='MyApp')
%form(ng-controller="TestDisplayErrorsAllKeys")
%p errors: {{ other_errors }}
%p nonEmpty(other_errors): {{ nonEmpty(other_errors) }}
%hr/
%div(display-errors-all-keys errors="other_errors")
%input(type="button" value="Add errors" ng-click="add_errors()")/
%input(type="button" value="Clear errors" ng-click="clear_errors()")/
我终于通过在我的作用域中定义一个帮助器方法并调用它($root.nonEmpty(errors)
)(参见jsfiddle的工作演示)来实现它。
这可能是漂亮的好解决方案,但是:
有没有更好的方法来解决这个问题?你会怎么做(写成ng-show
表达式)?
如何直接在Object.keys(errors).length
??
ng-show
让它工作?
醇>
答案 0 :(得分:10)
我会在指令范围内提供辅助函数(它是隔离的)。通常通过为指令提供链接功能:
.directive('displayErrorsAllKeys', function() {
return {
restrict: 'A',
scope: {
errors: '=',
debug: '@debug'
},
link: function (scope) {
scope.errorsExists = function(object) {
return object && Object.keys(object).length;
};
},
templateUrl: 'templates/display-errors-all-keys'
};
})
在根范围内放置逻辑和数据很少是一种好的做法。另请注意,我将函数命名为errorExists,它在实际表示错误时提供了som抽象。
关于第二个问题,您可以在链接功能中添加scope.Object = Object;
,但不要!此类特定逻辑不属于您的模板。模板应该关注是否显示错误,但不是为什么。
答案 1 :(得分:9)
这是我为解决此问题而添加的nonEmpty
过滤器(JavaScript equivalent)
.filter 'nonEmpty', ->
(object) ->
!! (object && Object.keys(object).length > 0)
试验:
%div {{ null | nonEmpty }} should be false
%div {{ { } | nonEmpty }} should be false
%div {{ {a: '1'} | nonEmpty }} should be true
上面示例中的ng-show条件可以简化为:
ng-show="errors | nonEmpty"
现在我可以轻松地重复使用此检查逻辑,而无需向我可能想要使用它的每个指令或控制器添加新方法。