Niezdefiniowany lub zerowy dla AngularJS

80

Kiedy piszę funkcje obsługi zegarka, sprawdzam parametr newVal na undefinedi null. Dlaczego AngularJS zachowuje się tak, ale nie ma określonej metody narzędziowej? Więc jest, angular.isUndefinedale nie ma angular.isUndefinedOrNull. Nie jest trudno to zaimplementować ręcznie, ale jak rozszerzyć kątowość, aby mieć tę funkcję w każdym kontrolerze? Tnx.

Edycja :

Przykład:

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

Czy takie postępowanie jest powszechnie przyjęte?

Edycja 2 :

Przykład JSFiddle ( 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);
    });
};
slo2ols
źródło
1
Możesz przejść na coffeescript. Istnieje operator Postifix ze znakiem zapytania, który to robi.
Patryk Ziemkowski 28.07.2013
czy mógłbyś podać prawdziwy przypadek, kiedy potrzebujesz takiej funkcjonalności?
Stepan Suvorov
3
Dlaczego nie stracić niezdefiniowanego czeku i po prostu sprawdzić newVal == null?
David Sherret
3
Ponieważ (newVal === null) zwraca false, jeśli newVal jest niezdefiniowane.
Greg Dougherty,
Tak, newVal === nullbędzie fałszywe, ale newVal == nullbędzie prawdziwe. David ma rację.
Patrick McElhaney,

Odpowiedzi:

160

Zawsze możesz dodać go dokładnie do swojej aplikacji

angular.isUndefinedOrNull = function(val) {
    return angular.isUndefined(val) || val === null 
}
Stepan Suvorov
źródło
Wiem, że nie zawsze dobrze jest rozszerzać biblioteki js w taki sposób, ale wygląda to bardzo blisko moich poszukiwań. Właściwie bardziej interesuje mnie, dlaczego w tym utknąłem. Czy standardową praktyką jest obsługiwanie wartości undefined i null w programach obsługujących zegarek?
slo2ols
Cóż, IMHO, w dobrze zorganizowanej aplikacji nie powinno być takich przypadków.
Stepan Suvorov
rozumiem, dzięki. Nadal jednak uważam, że „null” jest wynikiem prawidłowego doboru i należy je odróżnić od „undefined”.
Stepan Suvorov
24
@STEVER dlaczego „null” miałoby być złe w dobrze zorganizowanej aplikacji? Jeśli na przykład zmienna ma być wypełniona danymi użytkownika tylko wtedy, gdy użytkownik jest zalogowany, to null jest właściwą wartością przed zalogowaniem i po wylogowaniu.
RonLugge,
17

Proponuję wam napisanie własnej usługi komunalnej. Możesz dołączyć usługę do każdego kontrolera lub utworzyć kontroler nadrzędny, przypisać usługę narzędziową do swojego zakresu, a następnie każdy kontroler podrzędny odziedziczy to bez konieczności dołączania.

Przykład: 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;
});

Możesz też dodać go do rootScope. Tylko kilka opcji rozszerzenia kątowości o własne funkcje narzędziowe.

lucuma
źródło
4
Mocno wierzę, że funkcje narzędziowe nie powinny być DI
slo2ols.
@ slo2ols, aby go hermetyzować, możesz utworzyć usługę i wstrzyknąć ją tylko do roo
lucuma
14

Jakiś czas temu zadałem to samo pytanie opiekunom lodash, a oni odpowiedzieli, wspominając, że !=operator może być tutaj użyty:

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

Wykorzystuje to wymuszenie typu JavaScript do sprawdzenia wartości undefinedlub null.

Jeśli używasz JSHint do lintowania swojego kodu, dodaj następujące bloki komentarzy, aby powiedzieć mu, że wiesz, co robisz - większość czasu !=jest uważana za złą.

/* jshint -W116 */ 
if(newVal != null) {
/* jshint +W116 */
  // newVal is defined
}
Tom Spencer
źródło
9

Dlaczego po prostu nie użyć angular.isObjectz negacją? na przykład

if (!angular.isObject(obj)) {
    return;
}
Pete
źródło
... ale jest świetną opcją, jeśli wiesz, jakiego typu jest wartość i możesz wybrać angular.isXmetodę do dopasowania.
Phasmal
nulljest obiektem
spicykimchi
Z isObjectdokumentu: Zwraca: Prawda, jeśli valuejest, Objectale nie null.
DerMike
7

Odpowiedź @ STEVER jest zadowalająca. Pomyślałem jednak, że przydatne może być opublikowanie nieco innego podejścia. Używam metody o nazwie isValue, która zwraca true dla wszystkich wartości z wyjątkiem null, undefined, NaN i Infinity. Wstawienie NaN z null i undefined to dla mnie prawdziwa zaleta tej funkcji. Wrzucenie Infinity do wartości null i undefined jest bardziej dyskusyjne, ale szczerze mówiąc nie jest tak interesujące dla mojego kodu, ponieważ praktycznie nigdy nie używam Infinity.

Poniższy kod jest inspirowany przez Y.Lang.isValue . Oto źródło 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)));
};

Lub jako część fabryki

.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)));
  };
})
Steven Wexler
źródło
Dlaczego nie zamienić na val === null || !angular.isDefined(val)just val == null?
J.Steve,
3

lodash zapewnia skróconą metodę sprawdzania, czy jest niezdefiniowana lub zerowa: _.isNil(yourVariable)

nigong
źródło