Verificare se l'oggetto è vuoto, funziona con ng-show ma non dal controller?


99

Ho un oggetto JS dichiarato in questo modo

$scope.items = {};

Ho anche una richiesta $ http che riempie questo oggetto di elementi. Vorrei rilevare se questo elemento è vuoto, sembra che ng-show lo supporti ... Entro

ng-show="items"

e magicamente funziona, vorrei anche fare lo stesso da un controller ma non riesco a farlo funzionare, sembra che dovrei iterare sull'oggetto per vedere se ha proprietà o usare lodash o underscore .

C'è un'alternativa?

Ci ho provato

alert($scope.items == true);

ma restituisce sempre false, quando l'oggetto viene creato e quando viene popolato con $http, quindi non funziona in questo modo.


1
In un controller, stai solo usando javascript, quindi le risposte a questa domanda sarebbero valide
Cyrille Ka

Risposte:


62

Usa un valore letterale oggetto vuoto non è necessario qui, puoi usare null o undefined:

$scope.items = null;

In questo modo, ng-showdovrebbe continuare a funzionare e nel tuo controller puoi semplicemente fare:

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

E nei tuoi $httpcallback, fai quanto segue:

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

Ciao, grazie per la risposta, ma devo impostare le proprietà sull'oggetto prima di aver effettivamente ricevuto informazioni da $ http. se è nullo allora non potrei fare items.available = true potrei? Avevo l'impressione di dover creare un oggetto
Martin

Se ho un elemento = {}; non c'è comunque da confermare questo da un controller? ovviamente non sarebbe nullo qui.
Martin

1
Questo requisito non è nella tua domanda, quindi la mia risposta si basa sullo scenario semplificato. Se hai davvero bisogno di un oggetto con cui iniziare, puoi provare $scope.items = {available: false}, e ng-show="items.available", e nel tuo controller controlla if (items.available) {...}.
Ye Liu

Grazie! in realtà ho finito per testarlo con undefined e ha funzionato benissimo. Grazie.
Martin,

@YeLiu se vuoi rendere nullo un oggetto in oggetti, non ti sarà permesso di farlo due volte, angular lancerà un'eccezione che ti dice che non consente i duplicati all'interno di una raccolta per motivi sconosciuti per me finora.
Burimi

199

Oppure potresti mantenerlo semplice facendo qualcosa del genere:

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

Anche mio. Grazie al buon Dio non ho dovuto sovraccaricare più funzioni per testarlo.
Jimmy Kane

1
Solo una nota, per il mio test (chrome 45), anche l'uguaglianza di javascript semplice ha funzionato:({} === $scope.items)
Jesper Rønn-Jensen

hmm, questo restituisce falso, cosa dà? ({} == {})
chrismarx

Approccio molto intelligente! Le
battute

se utilizzato nella visualizzazione e utilizza il modello di visualizzazione come ambito, assicurati di aggiungere angolare al modello di visualizzazione, ad esempio vm.angular.equals ({}, items)
cinek

71

In un progetto privato un ha scritto questo filtro

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

utilizzo:

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

test:

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

});

Saluti.


2
Funziona come un fascino. Grazie per la condivisione!
Chnoch

2
Credo che i filtri debbano analizzare il contenuto e restituire un sottoinsieme del contenuto. Ciò che descrivi sembra più una funzione posta sull'ambito che un filtro. Vedere docs.angularjs.org/api/ng/filter/filter per ulteriori informazioni.
kmkm

4
Penso che tu stia parlando di un filtro particolare chiamato filter o 'filterFilter'. Un filtro in angolare può restituire tutto ciò che desideri, non solo un sottoinsieme dell'input fornito. Vedere docs.angularjs.org/api/ng/filter .
jcamelis

61

un altro semplice one-liner:

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

2
Questo è elegante, ma devi verificare la compatibilità ECMAScript5 nei browser a cui ti rivolgi. La trappola principale è che questo non funzionerà in IE8.
jmgem

8
Come tecnicità, angula non supporta ufficialmente IE8 nella (dev) ramo 1.3, e non se ne eseguono prove per esso sul 1.2 (stabile) docs.angularjs.org/guide/ie ... Inoltre, meno sosteniamo IE8, forse finalmente scomparirà. <inserire confutazione aziendale>
jaf0

2
La migliore risposta se devi davvero occuparti di un oggetto vuoto
Chovy

27

Se non puoi avere gli elementi OBJ uguali a null, puoi farlo:

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

e nella vista puoi fare:

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

Tu puoi fare

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

Solo se il tuo browser supporta ECMAScript 5. Ad esempio, IE 8 non supporta questa funzione.

Vedi http://kangax.github.io/compat-table/es5/ per maggiori informazioni


7
if( obj[0] )

una versione più pulita di questo potrebbe essere:

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

dove il risultato sarà indefinito se non è impostata alcuna proprietà dell'oggetto.


6

Oppure, se si utilizza lo-dash: _.empty (valore).

"Verifica se il valore è vuoto. Matrici, stringhe o oggetti argomenti con una lunghezza pari a 0 e gli oggetti senza proprietà enumerabili proprie sono considerati" vuoti "."


-2

Seleziona Oggetto vuoto

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

è solo sbagliato. Gli oggetti vuoti non possono essere testati in questo modo
kaiser

-11

puoi controllare la lunghezza degli articoli

ng-show="items.length"

1
Non capisco perché questa risposta ha -1 voti? Qualcuno può spiegarmelo per favore?
iluu

14
@KarolinaKafel perché itemsè un oggetto e gli oggetti non hanno .lengthproprietà (di solito) - gli array li hanno
llamerr

2
Non è un tipo di matrice :)
Ghazanfar Khan

@KarolinaKafel non è un array, quindi items.length è sempre indefinito.
Fabricio

Sì, quell'umano ha sbagliato, anche -1 avrebbe dimostrato che questa risposta è sbagliata, perché -10? le persone crescono :)
Aadam
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.