ตรวจสอบว่าวัตถุว่างเปล่าใช้ได้กับ ng-show แต่ไม่ใช่จากคอนโทรลเลอร์?


99

ฉันมีวัตถุ JS ที่ประกาศเช่นนั้น

$scope.items = {};

ฉันยังมีคำขอ $ http ที่เติมสิ่งของนี้ด้วยรายการ ฉันต้องการตรวจสอบว่ารายการนี้ว่างเปล่าหรือไม่ปรากฏว่า ng-show รองรับสิ่งนี้ ... ฉันป้อน

ng-show="items"

และมันใช้งานได้อย่างน่าอัศจรรย์ฉันก็อยากจะทำเช่นเดียวกันจากคอนโทรลเลอร์ แต่ดูเหมือนจะใช้งานไม่ได้ดูเหมือนว่าฉันอาจต้องทำซ้ำบนวัตถุเพื่อดูว่ามีคุณสมบัติหรือไม่ใช้ lodash หรือขีดล่าง .

มีทางเลือกอื่นไหม

ฉันไม่ได้ลอง

alert($scope.items == true);

แต่จะคืนค่าเป็นเท็จเสมอเมื่อวัตถุถูกสร้างขึ้นและเมื่อมีการเติมข้อมูล$httpดังนั้นจึงไม่ทำงานในลักษณะนั้น


1
ในคอนโทรลเลอร์คุณใช้ javascript ดังนั้นคำตอบของคำถามนี้จะถูกนำไปใช้: stackoverflow.com/questions/4994201/is-object-empty
Cyrille Ka

คำตอบ:


62

ไม่จำเป็นต้องใช้ตัวอักษรวัตถุว่างที่นี่คุณสามารถใช้ค่าว่างหรือไม่ได้กำหนด:

$scope.items = null;

ด้วยวิธีนี้ng-showควรทำงานต่อไปและในคอนโทรลเลอร์ของคุณคุณสามารถทำได้:

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

และในการ$httpโทรกลับของคุณคุณทำสิ่งต่อไปนี้:

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

สวัสดีขอบคุณสำหรับการตอบกลับ แต่ฉันต้องตั้งค่าคุณสมบัติบนวัตถุก่อนที่ฉันจะได้รับข้อมูลจาก $ http จริงๆ ถ้ามันเป็นโมฆะฉันก็ไม่สามารถทำ items.available = true ได้ไหม ฉันรู้สึกประทับใจที่ต้องสร้างวัตถุ
Martin

ถ้าฉันมีรายการ = {}; ไม่มีการยืนยันสิ่งนี้จากคอนโทรลเลอร์หรือไม่? แน่นอนว่ามันจะไม่เป็นโมฆะที่นี่
Martin

1
ข้อกำหนดนี้ไม่อยู่ในคำถามของคุณดังนั้นคำตอบของฉันจึงเป็นไปตามสถานการณ์ที่ง่ายกว่า หากคุณต้องการวัตถุจะเริ่มต้นด้วยจริงๆคุณสามารถลอง$scope.items = {available: false}และและในการควบคุมของคุณเพียงแค่ตรวจสอบng-show="items.available" if (items.available) {...}
Ye Liu

ขอบคุณ! จริงๆแล้วฉันลงเอยด้วยการทดสอบโดยไม่ได้กำหนดและมันก็ใช้งานได้ดี ขอบคุณ.
Martin

@YeLiu หากคุณต้องการสร้างไอเท็มในรายการที่เป็นโมฆะคุณจะไม่ได้รับอนุญาตให้ทำซ้ำสองครั้งเชิงมุมจะทำให้เกิดข้อยกเว้นซึ่งบอกคุณว่าไม่อนุญาตให้มีการทำสำเนาภายในคอลเลคชันโดยไม่ทราบสาเหตุสำหรับฉันจนถึงตอนนี้
Burimi

199

หรือคุณสามารถทำให้มันง่ายโดยทำสิ่งนี้:

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

เหมืองเช่นกัน. ขอบคุณพระเจ้าที่ดีฉันไม่ต้องโหลดฟังก์ชั่นมากเกินไปเพื่อทดสอบ
Jimmy Kane

1
โปรดทราบว่าสำหรับการทดสอบของฉัน (chrome 45) ความเท่าเทียมกันของจาวาสคริปต์อย่างง่ายก็ใช้ได้เช่นกัน:({} === $scope.items)
Jesper Rønn-Jensen

อืมนี่ประเมินว่าเป็นเท็จอะไรให้? ({} == {})
chrismarx

แนวทางฉลาดมาก! หนึ่งสมุทรดีกว่าเสมอ :)
supersan

หากใช้ในมุมมองและใช้โมเดลมุมมองเป็นขอบเขตตรวจสอบให้แน่ใจว่าคุณได้เพิ่มเชิงมุมในการดูโมเดลเช่น vm.angular.equals ({}, items)
cinek

71

ในโปรเจ็กต์ส่วนตัวเขียนตัวกรองนี้

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

การใช้งาน:

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

การทดสอบ:

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

});

ความนับถือ.


2
ใช้งานได้เหมือนมีเสน่ห์ ขอบคุณสำหรับการแบ่งปัน!
Chnoch

2
ฉันเชื่อว่าตัวกรองควรแยกวิเคราะห์เนื้อหาและส่งคืนเนื้อหาบางส่วน สิ่งที่คุณอธิบายดูเหมือนเป็นฟังก์ชันที่วางไว้บนขอบเขตมากกว่าตัวกรอง ดูข้อมูลเพิ่มเติมได้ที่docs.angularjs.org/api/ng/filter/filter
กม.

4
ฉันคิดว่าคุณกำลังพูดถึงตัวกรองเฉพาะที่เรียกว่าตัวกรองหรือ 'filterFilter' ตัวกรองในเชิงมุมสามารถส่งคืนทุกสิ่งที่คุณต้องการไม่ใช่แค่ส่วนย่อยของอินพุตที่กำหนด ดูdocs.angularjs.org/api/ng/filter
jcamelis

61

อีกหนึ่งซับง่ายๆ:

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

2
นี่เป็นสิ่งที่สวยงาม แต่คุณต้องตรวจสอบความเข้ากันได้ของ ECMAScript5 ในเบราว์เซอร์ที่คุณกำหนดเป้าหมาย ข้อผิดพลาดที่สำคัญคือสิ่งนี้ใช้ไม่ได้ใน IE8
jmgem

8
ในด้านเทคนิค angula ไม่สนับสนุน IE8 อย่างเป็นทางการในสาขา 1.3 (dev) และไม่ทำการทดสอบบน 1.2 (เสถียร) docs.angularjs.org/guide/ie ... ยิ่งไปกว่านั้นเราสนับสนุน IE8 น้อยลง บางทีมันอาจจะหายไปในที่สุด <ใส่ข้อโต้แย้งขององค์กร>
jaf0

2
คำตอบที่ดีที่สุดถ้าคุณต้องจัดการกับวัตถุว่างเปล่า
จริงๆ

27

หากคุณไม่มีรายการ OBJ เท่ากับ null คุณสามารถทำได้:

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

และในมุมมองคุณสามารถทำได้:

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

คุณทำได้

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

เฉพาะในกรณีที่เบราว์เซอร์ของคุณรองรับ ECMAScript 5 ตัวอย่างเช่น IE 8 ไม่รองรับคุณสมบัตินี้

ดูhttp://kangax.github.io/compat-table/es5/สำหรับข้อมูลเพิ่มเติม


7
if( obj[0] )

เวอร์ชันที่สะอาดกว่านี้อาจเป็น:

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

โดยที่ผลลัพธ์จะไม่ถูกกำหนดหากไม่มีการตั้งค่าคุณสมบัติวัตถุ


6

หรือถ้าใช้ lo-dash: _.empty (value)

"ตรวจสอบว่าค่าว่างหรือไม่อาร์เรย์สตริงหรืออาร์กิวเมนต์ออบเจ็กต์ที่มีความยาว 0 และอ็อบเจ็กต์ที่ไม่มีคุณสมบัติการนับของตัวเองจะถือว่า" ว่าง ""


-2

ตรวจสอบวัตถุว่างเปล่า

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

นั่นเป็นเรื่องผิด ไม่สามารถทดสอบวัตถุที่ว่างเปล่าเช่นนั้นได้
kaiser

-11

คุณสามารถตรวจสอบความยาวของรายการ

ng-show="items.length"

1
ฉันไม่เข้าใจว่าทำไมคำตอบนี้ถึงมี -1 โหวต? ใครช่วยอธิบายทีได้ไหม
iluu

14
@KarolinaKafel เพราะitemsเป็นวัตถุและวัตถุไม่มี.lengthคุณสมบัติ (โดยปกติ) - อาร์เรย์มี
llamerr

2
ไม่ใช่เพื่อนอาร์เรย์ :)
Ghazanfar Khan

@KarolinaKafel ไม่ใช่อาร์เรย์แล้ว items.length จะไม่ได้กำหนดเสมอ
Fabricio

ยาที่มนุษย์ทำผิด -1 ก็แสดงให้เห็นว่าคำตอบนี้ผิดทำไม -10? คนโตขึ้น :)
Aadam
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.