Không xác định hoặc null cho AngularJS


80

Khi tôi viết các chức năng xử lý đồng hồ, tôi kiểm tra tham số newVal trên undefinednull. Tại sao AngularJS có một hành vi như vậy, nhưng không có phương thức tiện ích cụ thể? Vì vậy, có angular.isUndefinednhưng không angular.isUndefinedOrNull. Không khó để thực hiện điều đó bằng tay nhưng làm thế nào để mở rộng góc để có chức năng đó trong mỗi bộ điều khiển? Tnx.

Chỉnh sửa :

Ví dụ:

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

Nó có được chấp nhận phổ biến để xử lý một cách như vậy không?

Chỉnh sửa 2 :

Ví dụ 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);
    });
};

1
Bạn có thể chuyển sang coffeescript. Có một toán tử postifix dấu hỏi thực hiện điều đó.
Patryk Ziemkowski

bạn có thể vui lòng đưa ra trường hợp thực tế khi bạn cần chức năng như vậy không?
Stepan Suvorov

3
Tại sao không mất kiểm tra không xác định và chỉ kiểm tra newVal == null?
David Sherret

3
Bởi vì (newVal === null) trả về false nếu newVal không được xác định.
Greg Dougherty

Đúng, newVal === nullsẽ sai, nhưng newVal == nullsẽ đúng. David đúng.
Patrick McElhaney

Câu trả lời:


160

Bạn luôn có thể thêm chính xác nó cho ứng dụng của mình

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

Tôi biết rằng không phải lúc nào cũng tốt để mở rộng thư viện js theo cách như vậy nhưng nó có vẻ rất gần với việc tìm kiếm của tôi. Trên thực tế, tôi quan tâm nhiều hơn đến lý do tại sao tôi mắc kẹt trong đó. Nó có phải là một phương pháp tiêu chuẩn để xử lý không xác định và null trong trình xử lý đồng hồ không?
slo2ols

Vâng, IMHO, trong ứng dụng có cấu trúc tốt sẽ không có những trường hợp như vậy.
Stepan Suvorov

hiểu rồi, thx. Nhưng tôi vẫn nghĩ rằng 'null' là kết quả của sự lựa chọn chính xác và nó nên được phân biệt với 'không xác định'.
Stepan Suvorov,

24
@STEVER tại sao 'null' lại tệ trong một ứng dụng có cấu trúc tốt? Ví dụ: nếu một biến chỉ nên được điền bằng dữ liệu người dùng khi người dùng đã đăng nhập, null là giá trị thích hợp trước khi đăng nhập và sau khi đăng xuất.
RonLugge

17

Gợi ý của tôi cho bạn là hãy viết dịch vụ tiện ích của riêng bạn. Bạn có thể bao gồm dịch vụ trong mỗi bộ điều khiển hoặc tạo bộ điều khiển mẹ, gán dịch vụ tiện ích cho phạm vi của bạn và sau đó mọi bộ điều khiển con sẽ kế thừa điều này mà bạn không cần phải bao gồm nó.

Ví dụ: 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;
});

Hoặc bạn cũng có thể thêm nó vào rootScope. Chỉ cần một số tùy chọn để mở rộng góc với các chức năng tiện ích của riêng bạn.


4
Tôi thực sự tin rằng các chức năng tiện ích không nên là DI
slo2ols

@ slo2ols để đóng gói nó, bạn có thể tạo ra một dịch vụ và tiêm nó chỉ đến roo
lucuma

14

Tôi đã hỏi câu hỏi tương tự của những người bảo trì dịch vụ lưu trú một thời gian trước và họ trả lời bằng cách đề cập đến !=toán tử có thể được sử dụng ở đây:

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

Điều này sử dụng cưỡng chế kiểu của JavaScript để kiểm tra giá trị cho undefinedhoặc null.

Nếu bạn đang sử dụng JSHint để bổ sung mã của mình, hãy thêm các khối nhận xét sau để cho nó biết rằng bạn biết bạn đang làm gì - hầu hết thời gian !=được coi là xấu.

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

9

Tại sao không chỉ sử dụng angular.isObjectvới phủ định? ví dụ

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

... nhưng là một lựa chọn tuyệt vời nếu bạn biết loại giá trị là gì và có thể chọn một angular.isXphương pháp để phù hợp.
Phasmal

nulllà một đối tượng
spicykimchi

Từ isObjecttài liệu: Trả về: Đúng nếu valuelà một Objectnhưng không null.
DerMike

7

Câu trả lời của @ STEVER là thỏa đáng. Tuy nhiên, tôi nghĩ có thể hữu ích nếu đăng một cách tiếp cận hơi khác. Tôi sử dụng một phương thức có tên isValue trả về true cho tất cả các giá trị ngoại trừ null, undefined, NaN và Infinity. Lồng trong NaN với null và không xác định là lợi ích thực sự của hàm đối với tôi. Việc gộp Infinity vào với null và undefined còn nhiều tranh cãi hơn, nhưng thành thật mà nói thì điều đó không thú vị với mã của tôi vì tôi thực tế không bao giờ sử dụng Infinity.

Đoạn mã sau được lấy cảm hứng từ Y.Lang.isValue . Đây là nguồn cho 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)));
};

Hoặc là một phần của nhà máy

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

Tại sao không thay thế val === null || !angular.isDefined(val)bằng chỉ val == null?
J.Steve

3

lodash cung cấp một phương thức viết tắt để kiểm tra xem không xác định hay không: _.isNil(yourVariable)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.