如何从指令模板访问 Object.keys(object).length? [英] How do I access Object.keys(object).length from a directive template?

查看:31
本文介绍了如何从指令模板访问 Object.keys(object).length?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to create a directive that will list all the errors contained in an errors object ({phone: ["is required"]}, but only if the object is non-empty. (It doesn't make sense to say "The following errors…" when there were none.)

我想出了如何通过测试 Object.keys(errors).length 来检查对象是否为空.问题是我不知道如何从指令模板访问 Object.keys.这可能吗?

I figured out how to check if an object is empty by testing Object.keys(errors).length. The problem is that I can't figure out how to access Object.keys from my directive template. Is this possible?

因为 Angular 表达式是在 scope 的上下文中而不是 inwindow 的上下文,我们无法从指令模板中访问诸如 Object 之类的东西,因为 Object 不是范围.(文档:表达式)

Since Angular expressions are "evaluated" (using $parse, not eval() ) in the context of a scope instead of in the context of window, we don't have access to things like Object from the directives template, because Object isn't a property of the scope. (Docs: Expressions)

到目前为止是有道理的.它继续说与 JavaScript 不同,它的名称默认为全局 window 属性,Angular 表达式必须显式使用 $window 来引用全局 windowcode> 对象.例如,如果要在表达式中调用 alert(),则必须使用 $window.alert().

Makes sense so far. It goes on to say that "Unlike JavaScript, where names default to global window properties, Angular expressions must use $window explicitly to refer to the global window object. For example, if you want to call alert() in an expression you must use $window.alert().

但我似乎无法访问 Object,即使我做了 $window.Object.我错过了什么?

But I can't seem to access Object even if I do $window.Object. What am I missing?

这是我正在调试的指令的代码(这里是一个 jsfiddle):

Here's the code for the directive I'm debugging (and here's a jsfiddle):

app.js.coffee:

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 = {}
])

display-errors-all-keys.ngt.haml:

display-errors-all-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-errors-all-keys.html.haml

test_ng_display-errors-all-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 用于工作演示).

I finally got it to work by defining a helper method in my scope and calling that instead ($root.nonEmpty(errors)) (see jsfiddle for working demo).

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

This is probably a pretty good solution, but:

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

如何直接在 ng-show 中使用 Object.keys(errors).length 让它工作??

How would I get it to work using Object.keys(errors).length directly in the ng-show??

推荐答案

我会在指令作用域(它是独立的)中提供辅助函数.通常通过为指令提供链接函数:

I would provide the helper function in the directives scope (which is isolated). Typically by providing a link function for the directive:

.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,它为错误的实际表示提供了一些抽象.

Placing logic and data in the root scope is seldom a good practice. Also note that I named the function errorExists, which provides som abstraction upon the actual representation of the errors.

对于你的第二个问题,你可以在你的链接函数中添加scope.Object = Object;,但是不要!这种具体的逻辑不属于你的模板.模板应该关注是否显示错误,而不是为什么.

As for your second question, you could add scope.Object = Object; in your link function, but DON'T! Such specific logic doesn't belong in your template. The template should be concerned with wether or not to show the errors, but not why.

这篇关于如何从指令模板访问 Object.keys(object).length?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆