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.