Vérifier si l'objet est vide, fonctionne avec ng-show mais pas depuis le contrôleur?


99

J'ai un objet JS déclaré comme ça

$scope.items = {};

J'ai également une requête $ http qui remplit cet objet avec des éléments. Je voudrais détecter si cet élément est vide, il semble que ng-show le supporte ... J'entre

ng-show="items"

et comme par magie, cela fonctionne, j'aimerais aussi faire la même chose à partir d'un contrôleur mais je n'arrive pas à le faire fonctionner, il semble que je devrais peut-être parcourir l'objet pour voir s'il a des propriétés ou utiliser un lodash ou un soulignement .

Y a-t-il une alternative?

J'ai essayé

alert($scope.items == true);

mais il retourne toujours false, lorsque l'objet est créé et lorsqu'il est rempli avec $http, donc cela ne fonctionne pas de cette façon.


1
Dans un contrôleur, vous utilisez simplement du javascript, donc les réponses à cette question s'appliqueraient: stackoverflow.com/questions/4994201/is-object-empty
Cyrille Ka

Réponses:


62

Utiliser un littéral d'objet vide n'est pas nécessaire ici, vous pouvez utiliser null ou undefined:

$scope.items = null;

De cette façon, ng-showdevrait continuer à fonctionner, et dans votre contrôleur, vous pouvez simplement faire:

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

Et dans vos $httprappels, vous effectuez les opérations suivantes:

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

Salut merci pour la réponse, mais je dois définir les propriétés de l'objet avant d'avoir réellement reçu des informations de $ http. si sa valeur est nulle, je ne pourrais pas faire des éléments. J'avais l'impression que je devais créer un objet
Martin

Si j'ai un élément = {}; n'y a-t-il pas de toute façon pour confirmer cela d'un contrôleur? bien sûr, ce ne serait pas nul ici.
Martin

1
Cette exigence n'est pas dans votre question, donc ma réponse est basée sur le scénario simplifié. Si vous avez vraiment besoin d'un objet pour commencer, vous pouvez essayer $scope.items = {available: false}, et ng-show="items.available", et dans votre contrôleur, vérifiez simplement if (items.available) {...}.
Ye Liu

Merci! en fait, j'ai fini par le tester avec undefined et cela a très bien fonctionné. Merci.
Martin

@YeLiu si vous voulez rendre un élément dans les éléments nul, vous ne serez pas autorisé à le faire deux fois, angular lancera une exception qui vous indiquera qu'il n'autorise pas les dupes dans une collection pour des raisons inconnues pour moi jusqu'à présent.
Burimi

199

Ou vous pouvez rester simple en faisant quelque chose comme ceci:

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

Le mien aussi. Merci mon Dieu, je n'ai pas eu à surcharger plus de fonctions pour le tester.
Jimmy Kane

1
Juste une note, pour mon test (chrome 45), la simple égalité javascript a également fonctionné:({} === $scope.items)
Jesper Rønn-Jensen

hmm, cela évalue faux, qu'est-ce qui donne? ({} == {})
chrismarx

Approche très intelligente! Une doublure est toujours meilleure :)
supersan

s'il est utilisé dans la vue et utilisez le modèle de vue comme champ d'application, assurez-vous d'ajouter angulaire au modèle de vue, c'est-à-dire vm.angular.equals ({}, items)
cinek

71

Dans un projet privé, a écrit ce filtre

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

usage:

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

essai:

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

});

Cordialement.


2
Fonctionne comme un charme. Merci d'avoir partagé!
Chnoch

2
Je pense que les filtres devraient analyser le contenu et renvoyer un sous-ensemble du contenu. Ce que vous décrivez ressemble plus à une fonction placée sur l'oscilloscope qu'à un filtre. Voir docs.angularjs.org/api/ng/filter/filter pour plus d'informations.
kmkm

4
Je pense que vous parlez d'un filtre particulier appelé filter ou «filterFilter». Un filtre angulaire peut renvoyer tout ce que vous voulez, pas seulement un sous-ensemble de l'entrée donnée. Voir docs.angularjs.org/api/ng/filter .
jcamelis

61

un autre simple one-liner:

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

2
C'est élégant, mais vous devez vérifier la compatibilité ECMAScript5 dans les navigateurs que vous ciblez. Le principal piège est que cela ne fonctionnera pas dans IE8.
jmgem

8
Pour des raisons techniques, angula ne prend pas officiellement en charge IE8 dans la branche 1.3 (dev), ni n'exécute de tests sur 1.2 (stable) docs.angularjs.org/guide/ie ... De plus, moins nous supportons IE8, peut-être qu'il disparaîtra finalement. <insérer la réfutation de l'entreprise>
jaf0

2
Meilleure réponse si vous devez vraiment faire face à un objet vide
chovy

27

Si vous ne pouvez pas avoir les éléments OBJ égaux à null, vous pouvez le faire:

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

et dans la vue, vous pouvez faire:

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

Tu peux faire

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

Uniquement si votre navigateur prend en charge ECMAScript 5. Par exemple, IE 8 ne prend pas en charge cette fonctionnalité.

Voir http://kangax.github.io/compat-table/es5/ pour plus d'informations


7
if( obj[0] )

une version plus propre de ceci pourrait être:

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

où le résultat ne sera pas défini si aucune propriété d'objet n'est définie.


6

Ou, si vous utilisez lo-dash: _.empty (valeur).

"Vérifie si la valeur est vide. Les tableaux, chaînes ou arguments, les objets avec une longueur de 0 et les objets sans propres propriétés énumérables sont considérés comme" vides "."


-2

Vérifier l'objet vide

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

c'est tout simplement faux. Les objets vides ne peuvent pas être testés comme ça
kaiser

-11

vous pouvez vérifier la longueur des articles

ng-show="items.length"

1
Je ne comprends pas pourquoi cette réponse a -1 voix? Quelqu'un peut-il m'expliquer cela s'il vous plaît?
iluu

14
@KarolinaKafel parce que itemsc'est un objet et que les objets n'ont pas de .lengthpropriété (généralement) - les tableaux les ont
llamerr

2
Ce n'est pas un mec de tableau :)
Ghazanfar Khan

@KarolinaKafel n'est pas un tableau, alors items.length est toujours indéfini.
Fabricio

Ya ya cet humain s'est trompé, -1 aurait aussi montré que cette réponse est fausse, pourquoi -10? les gens grandissent :)
Aadam
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.