【问题标题】:Checking if object is empty, works with ng-show but not from controller?检查对象是否为空,适用于 ng-show 但不适用于控制器?
【发布时间】:2013-07-24 05:33:47
【问题描述】:

我有一个这样声明的 JS 对象

$scope.items = {};

我还有一个 $http 请求,它用项目填充这个对象。我想检测这个项目是否为空,看来ng-show支持这个...我输入

ng-show="items"

神奇地它起作用了,我也想从控制器做同样的事情,但我似乎无法让它工作,看来我可能必须遍历对象以查看它是否有任何属性或使用lodash 或下划线。

还有其他选择吗?

我试过了

alert($scope.items == true);

但它总是返回 false ,当创建对象并填充 $http 时,所以它不能那样工作。

【问题讨论】:

标签: angularjs angularjs-scope


【解决方案1】:

检查空对象

$scope.isValid = function(value) {
    return !value
}

【讨论】:

  • 那是错误的。空对象不能这样测试
【解决方案2】:

您可以检查项目的长度

ng-show="items.length"

【讨论】:

  • 我不明白为什么这个答案有-1票?有人可以解释一下吗?
  • @KarolinaKafel 因为items 是一个对象,而对象没有.length 属性(通常)- 数组有它们
  • 这不是数组老兄:)
  • @KarolinaKafel 不是数组,因此 items.length 始终未定义。
  • 是啊,人类犯了错误,-1也表明这个答案是错误的,为什么-10?人们长大了:)
【解决方案3】:
if( obj[0] )

一个更简洁的版本可能是:

if( typeof Object.keys(obj)[0] === 'undefined' )

如果没有设置对象属性,结果将是未定义的。

【讨论】:

    【解决方案4】:

    或者,如果使用 lo-dash:_.empty(value)。

    “检查 value 是否为空。长度为 0 的数组、字符串或参数对象以及没有自己可枚举属性的对象被视为“空”。”

    【讨论】:

      【解决方案5】:

      如果你不能让项目 OBJ 等于 null,你可以这样做:

      $scope.isEmpty = function (obj) {
          for (var i in obj) if (obj.hasOwnProperty(i)) return false;
          return true;
      };
      

      在视图中你可以这样做:

      <div ng-show="isEmpty(items)"></div>
      

      你可以的

      var ob = {};
      Object.keys(ob).length
      

      仅当您的浏览器支持 ECMAScript 5。例如,IE 8 不支持此功能。

      更多信息请见http://kangax.github.io/compat-table/es5/

      【讨论】:

        【解决方案6】:

        另一个简单的单行:

        var ob = {};
        Object.keys(ob).length // 0
        

        【讨论】:

        • 这很优雅,但您必须检查您所针对的浏览器中的 ECMAScript5 兼容性。主要的缺陷是这在 IE8 中不起作用。
        • 从技术上讲,angula 并没有在 1.3(开发)分支中正式支持 IE8,也没有在 1.2(稳定)docs.angularjs.org/guide/ie 上运行测试...此外,我们支持的越少IE8,也许它最终会消失。
        • 如果你真的必须处理一个空对象的最佳答案
        【解决方案7】:

        或者您可以通过执行以下操作来保持简单:

        alert(angular.equals({}, $scope.items));
        

        【讨论】:

        • 我的也是。感谢上帝,我不必重载更多功能来测试它。
        • 请注意,对于我的测试(chrome 45),简单的 javascript 相等也有效:({} === $scope.items)
        • 嗯,这评估为假,什么给出? ({} == {})
        • 非常聪明的方法!一个衬垫总是更好:)
        • 如果在视图中使用并使用视图模型作为范围,请确保将角度添加到视图模型,即 vm.angular.equals({}, items)
        【解决方案8】:

        在一个私人项目中写了这个过滤器

        angular.module('myApp')
            .filter('isEmpty', function () {
                var bar;
                return function (obj) {
                    for (bar in obj) {
                        if (obj.hasOwnProperty(bar)) {
                            return false;
                        }
                    }
                    return true;
                };
            });
        

        用法:

        <p ng-hide="items | isEmpty">Some Content</p>
        

        测试:

        describe('Filter: isEmpty', function () {
        
            // load the filter's module
            beforeEach(module('myApp'));
        
            // initialize a new instance of the filter before each test
            var isEmpty;
            beforeEach(inject(function ($filter) {
                isEmpty = $filter('isEmpty');
            }));
        
            it('should return the input prefixed with "isEmpty filter:"', function () {
                  expect(isEmpty({})).toBe(true);
                  expect(isEmpty({foo: "bar"})).toBe(false);
            });
        
        });
        

        问候。

        【讨论】:

        • 像魅力一样工作。感谢分享!
        • 我相信过滤器应该解析内容并返回内容的子集。您所描述的似乎更像是放置在范围上的功能而不是过滤器。请参阅docs.angularjs.org/api/ng/filter/filter 了解更多信息。
        • 我认为您正在谈论一个称为过滤器或“filterFilter”的特定过滤器。角度过滤器可以返回您想要的任何内容,而不仅仅是给定输入的子集。见docs.angularjs.org/api/ng/filter
        【解决方案9】:

        这里不需要使用空的对象字面量,你可以使用 null 或 undefined:

        $scope.items = null;
        

        这样,ng-show 应该可以继续工作,在你的控制器中你可以这样做:

        if ($scope.items) {
            // items have value
        } else {
            // items is still null
        }
        

        在您的 $http 回调中,您执行以下操作:

        $http.get(..., function(data) {
            $scope.items = {
                data: data,
                // other stuff
            };
        });
        

        【讨论】:

        • 您好,感谢您的回复,但我需要先设置对象的属性,然后才能真正收到来自 $http 的信息。如果它为空,那么我不能做 items.available = true 可以吗?我的印象是我必须创建一个对象
        • 如果我有物品 = {};无论如何不能从控制器确认这一点?当然这里不会为空。
        • 这个要求不在你的问题中,所以我的回答是基于过度简化的场景。如果你真的需要一个对象,你可以试试$scope.items = {available: false}ng-show="items.available",然后在你的控制器中检查if (items.available) {...}
        • 谢谢!实际上,我最终用 undefined 对其进行了测试,并且效果很好。谢谢。
        • @YeLiu 如果你想让 items 中的一个项目为 null,你将不能重复两次,angular 会抛出一个异常,告诉你它不允许在一个集合中进行欺骗,原因不明我到目前为止。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-05
        • 1970-01-01
        • 2013-09-22
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        相关资源
        最近更新 更多