Kiểm tra xem đối tượng có trống không, hoạt động với ng-show nhưng không hoạt động với bộ điều khiển?


99

Tôi có một đối tượng JS được khai báo như vậy

$scope.items = {};

Tôi cũng có một yêu cầu $ http điền vào đối tượng này với các mục. Tôi muốn phát hiện xem mục này có trống không, có vẻ như ng-show hỗ trợ điều này ... Tôi nhập

ng-show="items"

và điều kỳ diệu là nó hoạt động, tôi cũng muốn làm điều tương tự từ một bộ điều khiển nhưng dường như tôi không thể làm cho nó hoạt động, có vẻ như tôi có thể phải lặp lại đối tượng để xem nó có bất kỳ thuộc tính nào không hoặc sử dụng dấu gạch ngang hoặc dấu gạch dưới .

Có giải pháp thay thế không?

Tôi đã thử

alert($scope.items == true);

nhưng nó luôn trả về false, khi đối tượng được tạo và khi được điền với $http, vì vậy nó không hoạt động theo cách đó.


1
Trong một bộ điều khiển, bạn chỉ cần sử dụng javascript, vì vậy câu trả lời của câu hỏi này sẽ được áp dụng: stackoverflow.com/questions/4994201/is-object-empty
Cyrille Ka

Câu trả lời:


62

Sử dụng một đối tượng rỗng theo nghĩa đen là không cần thiết ở đây, bạn có thể sử dụng null hoặc undefined:

$scope.items = null;

Bằng cách này, ng-showsẽ tiếp tục hoạt động và trong bộ điều khiển của bạn, bạn chỉ có thể làm:

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

Và trong các lệnh $httpgọi lại của mình , bạn thực hiện như sau:

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

Xin chào, cảm ơn bạn đã trả lời, nhưng tôi cần đặt thuộc tính trên đối tượng trước khi thực sự nhận được thông tin từ $ http. nếu nó null thì tôi không thể làm items.available = true tôi có thể không? Tôi đã theo ấn tượng mà tôi đã phải tạo ra một đối tượng
Martin

Nếu tôi có một mục = {}; không có cách nào để xác nhận điều này từ một bộ điều khiển? tất nhiên nó sẽ không rỗng ở đây.
Martin,

1
Yêu cầu này không có trong câu hỏi của bạn, vì vậy câu trả lời của tôi dựa trên kịch bản đơn giản hóa hơn. Nếu bạn thực sự cần một đối tượng để bắt đầu, bạn có thể thử $scope.items = {available: false}ng-show="items.available"và trong bộ điều khiển của bạn chỉ cần kiểm tra if (items.available) {...}.
Ye Liu,

cảm ơn! thực sự thì tôi đã thử nghiệm nó với undefined và nó hoạt động rất tốt. cảm ơn.
Martin

@YeLiu nếu bạn muốn tạo một mục trong các mục rỗng, bạn sẽ không được phép làm điều đó hai lần, angle sẽ đưa ra một ngoại lệ cho bạn biết rằng nó không cho phép lừa đảo trong một bộ sưu tập vì lý do không xác định đối với tôi cho đến nay.
Burimi

199

Hoặc bạn có thể làm cho nó đơn giản bằng cách làm như sau:

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

Tôi cũng thế. Cảm ơn chúa tốt, tôi đã không phải quá tải nhiều chức năng để kiểm tra nó.
Jimmy Kane,

1
Chỉ cần một lưu ý, đối với thử nghiệm của tôi (chrome 45), đơn giản bình đẳng javascript cũng làm việc:({} === $scope.items)
Jesper Ronn-Jensen

hmm, điều này được đánh giá là sai, điều gì mang lại? ({} == {})
chrismarx

Cách tiếp cận rất thông minh! Một lớp lót luôn tốt hơn :)
supersan

nếu được sử dụng trong quan điểm và sử dụng mô hình xem như phạm vi, hãy chắc chắn bạn thêm góc để xem mô hình, tức là vm.angular.equals ({}, items)
Cinek

71

Trong một dự án riêng tư, một người đã viết bộ lọc này

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

sử dụng:

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

thử nghiệm:

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

});

Trân trọng.


2
Hoạt động như một sự quyến rũ. Cám ơn vì đã chia sẻ!
Chnoch

2
Tôi tin rằng các bộ lọc sẽ phân tích cú pháp nội dung và trả về một tập hợp con của nội dung. Những gì bạn mô tả có vẻ giống một hàm được đặt trên phạm vi hơn là một bộ lọc. Xem docs.angularjs.org/api/ng/filter/filter để biết thêm thông tin.
kmkm

4
Tôi nghĩ rằng bạn đang nói về một bộ lọc cụ thể được gọi là bộ lọc hoặc 'filterFilter'. Bộ lọc ở dạng góc có thể trả về bất kỳ thứ gì bạn muốn, không chỉ là một tập hợp con của đầu vào đã cho. Xem docs.angularjs.org/api/ng/filter .
jcamelis

61

một lớp lót đơn giản khác:

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

2
Điều này thật thanh lịch, nhưng bạn phải kiểm tra khả năng tương thích của ECMAScript5 trong các trình duyệt bạn đang nhắm mục tiêu. Cạm bẫy chính là điều này sẽ không hoạt động trong IE8.
jmgem

8
Về mặt kỹ thuật, angula không chính thức hỗ trợ IE8 trong nhánh 1.3 (dev), cũng như họ không chạy thử nghiệm cho nó trên 1.2 (ổn định) docs.angularjs.org/guide/ie ... Hơn nữa, chúng tôi càng ít hỗ trợ IE8, có lẽ cuối cùng nó sẽ biến mất. <chèn lời bác bỏ của công ty>
jaf0

2
Câu trả lời hay nhất nếu bạn thực sự phải đối phó với một vật thể rỗng
chovy

27

Nếu bạn không thể có các mục OBJ bằng null, bạn có thể làm điều này:

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

và trong quan điểm bạn có thể làm:

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

Bạn có thể làm

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

Chỉ khi trình duyệt của bạn hỗ trợ ECMAScript 5. Ví dụ, IE 8 không hỗ trợ tính năng này.

Xem http://kangax.github.io/compat-table/es5/ để biết thêm thông tin


7
if( obj[0] )

một phiên bản rõ ràng hơn của điều này có thể là:

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

trong đó kết quả sẽ không được xác định nếu không có thuộc tính đối tượng nào được đặt.


6

Hoặc, nếu sử dụng lo-dash: _.empty (value).

"Kiểm tra xem giá trị có trống không. Các đối tượng mảng, chuỗi hoặc đối số có độ dài bằng 0 và các đối tượng không có thuộc tính liệt kê riêng được coi là" trống "."


-2

Kiểm tra đối tượng rỗng

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

thật tồi tệ. Đối tượng rỗng không thể được kiểm tra như thế
kaiser

-11

bạn có thể kiểm tra độ dài của các mặt hàng

ng-show="items.length"

1
Tôi không hiểu tại sao câu trả lời này có -1 phiếu bầu? Ai đó có thể giải thích cho tôi điều đó được không?
iluu

14
@KarolinaKafel vì itemslà một đối tượng và các đối tượng không có .lengthtài sản (thường) - mảng có họ
llamerr

2
Nó không phải là một anh chàng mảng :)
Ghazanfar Khan

@KarolinaKafel không phải là một mảng thì items.length luôn là không xác định.
Fabricio

Ya ya rằng con người đã sai, -1 cũng sẽ cho thấy rằng câu trả lời này là sai, tại sao -10? mọi người lớn lên :)
Aadam
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.