Проверка того, пустой ли объект, работает с 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));
тестирование123
источник
Моя тоже. Слава богу, мне не пришлось перегружать дополнительные функции, чтобы проверить это.
Джимми Кейн
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);
    });

});

С уважением.

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

mattia.corci
источник
7
if( obj[0] )

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

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

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

n0mad
источник
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