Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 如何从指令模板访问Object.keys(Object).length?_Angularjs_Angularjs Directive - Fatal编程技术网

Angularjs 如何从指令模板访问Object.keys(Object).length?

Angularjs 如何从指令模板访问Object.keys(Object).length?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我正在尝试创建一个指令,该指令将列出errors对象中包含的所有错误({phone:[“is required”]},但仅当对象为非空时才执行(没有错误时,说“以下错误…”没有意义) 我通过测试object.keys(errors).length了解了如何检查对象是否为空。问题是我无法了解如何从指令模板访问object.keys。这可能吗 由于角度表达式是在范围的上下文中而不是在窗口的上下文中“计算”(使用$parse,而不是eval())的,因此我们无法从指令模板访问对象之类的内容,因为对象不

我正在尝试创建一个指令,该指令将列出errors对象中包含的所有错误(
{phone:[“is required”]
},但仅当对象为非空时才执行(没有错误时,说“以下错误…”没有意义)

我通过测试
object.keys(errors).length了解了如何检查对象是否为空。问题是我无法了解如何从指令模板访问object.keys。这可能吗

由于角度表达式是在
范围
的上下文中而不是在
窗口
的上下文中“计算”(使用
$parse
,而不是
eval()
)的,因此我们无法从指令模板访问
对象
之类的内容,因为
对象
不是范围的属性。(文档:)

到目前为止是有意义的。它接着说,“与JavaScript不同,JavaScript的名称默认为全局<代码>窗口
属性,角度表达式必须使用<代码>$window显式引用全局<代码>窗口对象。例如,如果要在表达式中调用<代码>警报(),则必须使用<代码>$window.alert()

但是我似乎无法访问
对象
,即使我访问了
$window.Object
。我缺少什么


以下是我正在调试的指令的代码(以下是一个示例):

app.js.coffee:

…
.指令“displayErrorsAllKeys”,->
{
限制:“A”,
范围:{
错误:'='
调试:“@debug”
}
templateUrl:“模板/显示错误所有键”
}
.run(['$rootScope',($rootScope)->
$rootScope.nonEmpty=(对象)->
!!对象。键(对象)。长度
])
.controller('TestDisplayErrorsAllKeys',
[“$scope”,
($scope)->
$scope.other_errors={}
$scope.add_errors=->
$scope.other_errors={“姓氏”:[“是必需的],“电话”:[“是必需的”]}
$scope.clear\u错误=->
$scope.other_errors={}
])
display-errors-all-keys.ngt.haml:

.errors(ng show=“$window.Object.keys(errors).length>0”)
%p以下错误导致无法保存:
%div(ng repeat=“(key,error_messages)in errors”){{key}}:{{{error_messages}toSentence}
test_ng_display-errors-all-keys.html.haml

:scss
.错误{
颜色:红色;
}
%分区(ng app='MyApp')
%表单(ng controller=“TestDisplayErrorsAllKeys”)
%p错误:{{其他错误}}
%p非空(其他错误):{{{nonEmpty(其他错误)}
%人力资源/
%div(显示错误所有键错误=“其他错误”)
%输入(type=“button”value=“Add errors”ng click=“Add_errors()”)/
%输入(type=“button”value=“Clear errors”ng click=“Clear\u errors()”)/
通过在我的作用域中定义一个helper方法并调用它(
$root.nonEmpty(errors)
)(请参阅工作演示),我最终实现了它

这可能是一个很好的解决方案,但是:

  • 有没有更好的方法来解决这个问题?你会怎么做(编写
    ng show
    表达式)

  • 如何在
    ng show
    中直接使用
    Object.keys(errors).length


  • 我将在指令范围内提供帮助函数(这是独立的)。通常通过为指令提供链接函数:

    .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命名为errorExists,它根据错误的实际表示提供了som抽象


    至于你的第二个问题,你可以在你的链接函数中添加
    scope.Object=Object;
    ,但是不要!这样的特定逻辑不属于你的模板。模板应该关注是否显示错误,而不是原因。

    这里是我为解决这个问题而添加的
    非空的
    过滤器()

    测试:

    %div {{ null | nonEmpty }} should be false
    %div {{ { } | nonEmpty }} should be false
    %div {{ {a: '1'} | nonEmpty }} should be true
    
    上述示例中的我的ng show条件可以简化为:

    ng-show="errors | nonEmpty"
    

    现在我可以很容易地重用这个检查逻辑,而不必在我可能要使用它的每个指令或控制器中添加新方法。

    回答得好,解释得好!尽管我仍然希望有一种更简单的方法来检查模板中的对象是否为非空,比如(现在我想到它)可能是一个过滤器:
    ng show=”errors | nonEmpty“
    …过滤器可能是一个非常好的主意,我同意!它读起来很好,并提供了一定程度的抽象。能够检查整个应用程序中是否存在错误似乎是一个合理的理由。
    ng-show="errors | nonEmpty"