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.

Martin
la source
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
    };
});
Ye Liu
la source
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));
testing123
la source
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.

jcamelis
la source
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
jaf0
la source
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

mattia.corci
la source
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.

n0mad
la source
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 "."

Jeff Pace
la source
-2

Vérifier l'objet vide

$scope.isValid = function(value) {
    return !value
}
Taran
la source
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"
Pradip Chongbang
la source
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