Undefiniert oder null für AngularJS


80

Wenn ich Uhrhandhabungsfunktionen schreibe, überprüfe ich newVal param on undefinedund null. Warum hat AngularJS ein solches Verhalten, aber keine spezielle Dienstprogrammmethode? Also gibt es angular.isUndefineddoch nicht angular.isUndefinedOrNull. Es ist nicht schwer, dies von Hand zu implementieren, aber wie weit ist der Winkel, um diese Funktion in jedem Controller zu haben? Tnx.

Bearbeiten :

Das Beispiel:

$scope.$watch("model", function(newVal) {
    if (angular.isUndefined(newVal) || newVal == null) return;
    // do somethings with newVal
}

Ist es allgemein anerkannt, so umzugehen?

Bearbeiten 2 :

Das JSFiddle-Beispiel ( http://jsfiddle.net/ubA9r/ ):

<div ng-app="App">
  <div ng-controller="MainCtrl"> 
      <select ng-model="model" ng-options="m for m in models">
          <option value="" class="ng-binding">Choose model</option>
      </select>
      {{model}}
  </div>
</div>

var app = angular.module("App", []);

var MainCtrl = function($scope) {
    $scope.models = ['Apple', 'Banana'];
    $scope.$watch("model", function(newVal) {
        console.log(newVal);
    });
};

1
Sie könnten zu Coffeescript wechseln. Es gibt einen Fragezeichen-Postifix-Operator, der dies tut.
Patryk Ziemkowski

Könnten Sie bitte den tatsächlichen Fall angeben, wenn Sie eine solche Funktionalität benötigen?
Stepan Suworow

3
Warum nicht den undefinierten Scheck verlieren und einfach prüfen newVal == null?
David Sherret

3
Weil (newVal === null) false zurückgibt, wenn newVal undefiniert ist.
Greg Dougherty

Ja, newVal === nullwird falsch sein, aber newVal == nullwird wahr sein. David ist richtig.
Patrick McElhaney

Antworten:


160

Sie können es jederzeit genau für Ihre Anwendung hinzufügen

angular.isUndefinedOrNull = function(val) {
    return angular.isUndefined(val) || val === null 
}

Ich weiß, dass es nicht immer gut ist, js Bibliotheken so zu erweitern, aber es kommt meiner Suche sehr nahe. Eigentlich interessiert mich mehr, warum ich dabei geblieben bin. Ist es eine Standardpraxis, in Watch-Handlern undefiniert und null zu behandeln?
Slo2ols

Nun, IMHO, in einer gut strukturierten Anwendung sollte es solche Fälle nicht geben.
Stepan Suworow

verstanden, danke. Aber ich denke immer noch, dass 'null' ein Ergebnis der richtigen Auswahl ist und von 'undefiniert' unterschieden werden sollte.
Stepan Suworow

24
@STEVER warum sollte 'null' in einer gut strukturierten Anwendung schlecht sein? Wenn eine Variable beispielsweise nur dann mit Benutzerdaten gefüllt werden soll, wenn der Benutzer angemeldet ist, ist null der richtige Wert vor dem Anmelden und nach dem Abmelden.
RonLugge

17

Mein Vorschlag an Sie ist, Ihren eigenen Dienstprogrammdienst zu schreiben. Sie können den Dienst in jeden Controller aufnehmen oder einen übergeordneten Controller erstellen, den Dienstprogrammdienst Ihrem Bereich zuweisen, und dann erbt jeder untergeordnete Controller diesen, ohne dass Sie ihn einschließen müssen.

Beispiel: http://plnkr.co/edit/NI7V9cLkQmEtWO36CPXy?p=preview

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, Utils) {
    $scope.utils = Utils;
});

app.controller('ChildCtrl', function($scope, Utils) {
   $scope.undefined1 = Utils.isUndefinedOrNull(1);  // standard DI
   $scope.undefined2 = $scope.utils.isUndefinedOrNull(1);  // MainCtrl is parent

});

app.factory('Utils', function() {
  var service = {
     isUndefinedOrNull: function(obj) {
         return !angular.isDefined(obj) || obj===null;
     }

  }

  return service;
});

Oder Sie können es auch dem rootScope hinzufügen. Nur ein paar Optionen zum Erweitern des Winkels mit Ihren eigenen Dienstprogrammfunktionen.


4
Ich bin der
festen

@ slo2ols es kapseln Sie einen Dienst erstellen kann und es nur auf die roo injizieren
lucuma

14

Ich habe vor einiger Zeit die gleiche Frage an die Lodash-Betreuer gestellt, und sie antworteten mit der Erwähnung, dass der !=Betreiber hier verwendet werden kann:

if(newVal != null) {
  // newVal is defined
}

Hierbei wird der Typzwang von JavaScript verwendet, um den Wert für zu überprüfen undefined odernull .

Wenn Sie JSHint verwenden, um Ihren Code zu fusseln, fügen Sie die folgenden Kommentarblöcke hinzu, um anzuzeigen, dass Sie wissen, was Sie tun - die meiste Zeit !=wird als schlecht angesehen.

/* jshint -W116 */ 
if(newVal != null) {
/* jshint +W116 */
  // newVal is defined
}

9

Warum nicht einfach angular.isObjectmit Negation verwenden? z.B

if (!angular.isObject(obj)) {
    return;
}

... ist aber eine gute Option, wenn Sie wissen, um welchen Typ es sich handelt, und eine angular.isXpassende Methode auswählen können .
Phasmal

nullist ein Objekt
spicykimchi

Aus dem isObjectDokument: Rückgabe: True if valueist ein Objectaber nicht null.
DerMike

7

Die Antwort von @ STEVER ist zufriedenstellend. Ich hielt es jedoch für nützlich, einen etwas anderen Ansatz zu veröffentlichen. Ich verwende eine Methode namens isValue, die für alle Werte außer null, undefined, NaN und Infinity true zurückgibt. Das Zusammenfassen von NaN mit null und undefiniert ist für mich der eigentliche Vorteil der Funktion. Infinity mit null und undefined zusammenzufassen ist umstrittener, aber ehrlich gesagt nicht so interessant für meinen Code, da ich Infinity praktisch nie benutze.

Der folgende Code ist von Y.Lang.isValue inspiriert . Hier ist die Quelle für Y.Lang.isValue.

/**
 * A convenience method for detecting a legitimate non-null value.
 * Returns false for null/undefined/NaN/Infinity, true for other values,
 * including 0/false/''
 * @method isValue
 * @static
 * @param o The item to test.
 * @return {boolean} true if it is not null/undefined/NaN || false.
 */
angular.isValue = function(val) {
  return !(val === null || !angular.isDefined(val) || (angular.isNumber(val) && !isFinite(val)));
};

Oder als Teil einer Fabrik

.factory('lang', function () {
  return {
    /**
     * A convenience method for detecting a legitimate non-null value.
     * Returns false for null/undefined/NaN/Infinity, true for other values,
     * including 0/false/''
     * @method isValue
     * @static
     * @param o The item to test.
     * @return {boolean} true if it is not null/undefined/NaN || false.
     */
    isValue: function(val) {
      return !(val === null || !angular.isDefined(val) || (angular.isNumber(val) && !isFinite(val)));
  };
})

Warum nicht durch val === null || !angular.isDefined(val)nur ersetzen val == null?
J.Steve

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.