Sprawdzanie, czy obiekt jest pusty, działa z ng-show, ale nie z kontrolera?

99

Mam zadeklarowany obiekt JS w ten sposób

$scope.items = {};

Mam również żądanie $ http, które wypełnia ten obiekt elementami. Chciałbym sprawdzić, czy ta pozycja jest pusta, wygląda na to, że ng-show obsługuje to ... Wchodzę

ng-show="items"

i magicznie to działa, chciałbym też zrobić to samo z kontrolera, ale nie wydaje mi się, żebym to działał, wygląda na to, że być może będę musiał iterować po obiekcie, aby sprawdzić, czy ma jakieś właściwości lub użyć lodash lub podkreślenia .

Czy jest alternatywa?

Próbowałem

alert($scope.items == true);

ale zawsze zwraca false, gdy obiekt jest tworzony i wypełniany $http, więc nie działa w ten sposób.

Jaskółka oknówka
źródło
1
W kontrolerze używasz tylko javascript, więc odpowiedzi na to pytanie będą miały zastosowanie: stackoverflow.com/questions/4994201/is-object-empty
Cyrille Ka

Odpowiedzi:

62

Użyj pustego literału obiektu nie jest tutaj konieczne, możesz użyć wartości null lub undefined:

$scope.items = null;

W ten sposób ng-showpowinien działać dalej, aw swoim kontrolerze możesz po prostu:

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

W swoich $httpcallbackach wykonujesz następujące czynności:

$http.get(..., function(data) {
    $scope.items = {
        data: data,
        // other stuff
    };
});
Ye Liu
źródło
Cześć dziękuję za odpowiedź, ale muszę ustawić właściwości obiektu, zanim faktycznie otrzymam informacje z $ http. jeśli ma wartość null, nie mogę zrobić items.available = true, prawda? Miałem wrażenie, że muszę stworzyć obiekt
Martin
Jeśli mam elementy = {}; czy w ogóle nie ma potwierdzenia tego od kontrolera? oczywiście nie byłoby tutaj zerowe.
Martin
1
Tego wymagania nie ma w Twoim pytaniu, więc moja odpowiedź opiera się na zbyt uproszczonym scenariuszu. Jeśli naprawdę potrzebujesz obiektu na początek, możesz spróbować $scope.items = {available: false}i ng-show="items.available", aw kontrolerze po prostu sprawdź if (items.available) {...}.
Ye Liu,
dzięki! w rzeczywistości skończyło się na testowaniu go z undefined i działało świetnie. dzięki.
Martin,
@YeLiu jeśli chcesz, aby pozycja w elementach była zerowa, nie będziesz mógł tego zrobić dwukrotnie, angular rzuci wyjątek, który mówi, że nie zezwala na duplikaty w kolekcji z nieznanych dotąd powodów.
Burimi
199

Lub możesz to uprościć, robiąc coś takiego:

alert(angular.equals({}, $scope.items));
testowanie123
źródło
Mój też. Dzięki dobry panie, nie musiałem przeciążać więcej funkcji, aby to przetestować.
Jimmy Kane
1
Tylko uwaga, w moim teście (chrome 45) działała również prosta równość javascript:({} === $scope.items)
Jesper Rønn-Jensen
hmm, to daje fałsz, co daje? ({} == {})
chrismarx
Bardzo sprytne podejście! Jeden
wkład
jeśli jest używany w widoku i użyj modelu widoku jako zakresu, pamiętaj, aby dodać kątowy do modelu widoku, tj. vm.angular.equals ({}, items)
cinek
71

W prywatnym projekcie napisał ten filtr

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

stosowanie:

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

testowanie:

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

});

pozdrowienia.

jcamelis
źródło
2
Działa jak marzenie. Dzięki za udostępnienie!
Chnoch
2
Uważam, że filtry powinny analizować zawartość i zwracać podzbiór treści. To, co opisujesz, wydaje się bardziej funkcją umieszczoną w zasięgu niż filtrem. Więcej informacji można znaleźć w docs.angularjs.org/api/ng/filter/filter .
kmkm
4
Myślę, że mówisz o konkretnym filtrze o nazwie filter lub „filterFilter”. Filtr w angular może zwrócić wszystko, co chcesz, a nie tylko podzbiór danego wejścia. Zobacz docs.angularjs.org/api/ng/filter .
jcamelis
61

kolejny prosty jednolinijkowy:

var ob = {};
Object.keys(ob).length // 0
jaf0
źródło
2
Jest to eleganckie, ale musisz sprawdzić zgodność ECMAScript5 w przeglądarkach, na które kierujesz reklamy. Główną pułapką jest to, że to nie zadziała w IE8.
jmgem
8
Technicznie rzecz biorąc, angula oficjalnie nie obsługuje IE8 w gałęzi 1.3 (dev), ani nie przeprowadza testów dla niej w wersji 1.2 (stabilnej) docs.angularjs.org/guide/ie ... Ponadto im mniej wspieramy IE8, może w końcu zniknie. <wstaw
obalenie
2
Najlepsza odpowiedź, jeśli naprawdę musisz poradzić sobie z pustym przedmiotem
chovy
27

Jeśli nie możesz mieć pozycji OBJ równych null, możesz to zrobić:

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

aw widoku możesz:

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

Możesz to zrobić

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

Tylko jeśli Twoja przeglądarka obsługuje ECMAScript 5. Na przykład IE 8 nie obsługuje tej funkcji.

Więcej informacji można znaleźć pod adresem http://kangax.github.io/compat-table/es5/

mattia.corci
źródło
7
if( obj[0] )

bardziej przejrzystą wersją może być:

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

gdzie wynik będzie niezdefiniowany, jeśli żadna właściwość obiektu nie zostanie ustawiona.

n0mad
źródło
6

Lub, jeśli używasz lo-dash: _.empty (wartość).

„Sprawdza, czy wartość jest pusta. Tablice, łańcuchy lub obiekty argumentów o długości 0 i obiekty bez własnych wyliczalnych właściwości są uznawane za„ puste ”.

Jeff Pace
źródło
-2

Sprawdź pusty obiekt

$scope.isValid = function(value) {
    return !value
}
Taran
źródło
to jest po prostu złe. Pustych obiektów nie da się w ten sposób przetestować
kaiser
-11

możesz sprawdzić długość przedmiotów

ng-show="items.length"
Pradip Chongbang
źródło
1
Nie rozumiem, dlaczego ta odpowiedź ma -1 głosów? Czy ktoś może mi to wyjaśnić?
iluu
14
@KarolinaKafel, ponieważ itemsjest obiektem, a obiekty nie mają .lengthwłaściwości (zwykle) - tablice je mają
llamerr
2
To nie jest tablica koleś :)
Ghazanfar Khan
@KarolinaKafel nie jest tablicą, wtedy items.length jest zawsze niezdefiniowana.
Fabricio
Tak, ten człowiek popełnił błąd, -1 również pokazałoby, że ta odpowiedź jest błędna, dlaczego -10? ludzie dorastają :)
Aadam