Проверка того, пустой ли объект, работает с ng-show, но не с контроллера?


99

У меня есть объект JS, объявленный так

$scope.items = {};

У меня также есть запрос $ http, который заполняет этот объект элементами. Я хотел бы определить, пуст ли этот элемент, похоже, что ng-show поддерживает это ... Я ввожу

ng-show="items"

и волшебным образом это работает, я также хотел бы сделать то же самое с контроллера, но я не могу заставить его работать, похоже, мне, возможно, придется перебирать объект, чтобы увидеть, есть ли у него какие-либо свойства, или использовать lodash или подчеркивание .

Есть ли альтернатива?

Я действительно пробовал

alert($scope.items == true);

но он всегда возвращает false, когда объект создается и когда он заполняется $http, поэтому он не работает таким образом.


1
В контроллере вы просто используете javascript, поэтому будут применяться ответы на этот вопрос: stackoverflow.com/questions/4994201/is-object-empty
Cyrille Ka

Ответы:


62

Использовать пустой литерал объекта здесь не обязательно, вы можете использовать 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. если его значение равно null, то я не смогу сделать items.available = true, не так ли? У меня создалось впечатление, что я должен создать объект
Мартин

Если у меня есть items = {}; в любом случае нет возможности подтвердить это от контроллера? конечно, здесь он не будет нулевым.
Martin

1
Это требование отсутствует в вашем вопросе, поэтому мой ответ основан на слишком упрощенном сценарии. Если вам действительно нужен объект , чтобы начать с, вы можете попробовать $scope.items = {available: false}, и ng-show="items.available", в контроллере просто проверить if (items.available) {...}.
Е Лю

Спасибо! на самом деле я закончил тестирование с помощью undefined, и он отлично работал. Спасибо.
Martin

@YeLiu, если вы хотите сделать элемент в элементах null, вам не разрешат сделать это дважды, angular выдаст исключение, в котором говорится, что он не разрешает дублирование в коллекции по неизвестным для меня причинам.
Burimi

199

Или вы могли бы упростить, сделав что-то вроде этого:

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

Моя тоже. Слава богу, мне не пришлось перегружать дополнительные функции, чтобы проверить это.
Джимми Кейн

1
Просто примечание, для моего теста (chrome 45) также работало простое равенство javascript:({} === $scope.items)
Jesper Rønn-Jensen

хм, это оценивается как ложь, что дает? ({} == {})
chrismarx

Очень умный подход! Один
supersan

при использовании в представлении и использовании модели представления в качестве области видимости убедитесь, что вы добавили angular для модели просмотра, т.е. vm.angular.equals ({}, items)
cinek

71

В частном проекте a написал этот фильтр

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);
    });

});

С уважением.


2
Работает как шарм. Спасибо, что поделился!
Чноч

2
Я считаю, что фильтры должны анализировать контент и возвращать подмножество контента. То, что вы описываете, больше похоже на функцию, помещенную в область видимости, чем на фильтр. См. Docs.angularjs.org/api/ng/filter/filter для получения дополнительной информации.
кмкм 01

4
Я думаю, что вы говорите о конкретном фильтре, который называется filter или filterFilter. Фильтр в angular может возвращать все, что вы хотите, а не только подмножество заданного ввода. См. Docs.angularjs.org/api/ng/filter .
jcamelis

61

еще один простой однострочный:

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

2
Это элегантно, но вы должны проверить совместимость ECMAScript5 в браузерах, на которые вы нацеливаетесь. Основная ошибка в том, что это не будет работать в IE8.
jmgem

8
Технически, angula официально не поддерживает IE8 в ветке 1.3 (dev), и они не запускают для него тесты в 1.2 (стабильной) docs.angularjs.org/guide/ie ... Более того, чем меньше мы поддерживаем IE8, может быть, это окончательно исчезнет. <вставить корпоративное опровержение>
jaf0

2
Лучший ответ, если вам действительно нужно иметь дело с пустым предметом
Чови

27

Если у вас не может быть элементов OBJ, равных нулю, вы можете сделать это:

$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/ для получения дополнительной информации.


7
if( obj[0] )

более чистая версия этого может быть:

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

где результат будет неопределенным, если свойство объекта не задано.


6

Или, если используется нижнее тире: _.empty (значение).

«Проверяет, является ли значение пустым. Массивы, строки или объекты аргументов с длиной 0 и объекты без собственных перечислимых свойств считаются« пустыми ».


-2

Проверить пустой объект

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

это просто неправильно. Пустые объекты нельзя так тестировать
kaiser

-11

вы можете проверить длину предметов

ng-show="items.length"

1
Я не понимаю, почему у этого ответа -1 голос? Может кто-нибудь объяснить мне это, пожалуйста?
iluu

14
@KarolinaKafel, потому что itemsэто объект, а объекты не имеют .lengthсвойств (обычно) - они есть в массивах
llamerr

2
Это не
массивный

@KarolinaKafel не является массивом, тогда items.length всегда не определено.
Fabricio

Я, ты, этот человек сделал ошибку, -1 также показал бы, что этот ответ неверен, почему -10? люди растут :)
Aadam
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.