2013-04-02 25 views
9

Tôi đã tạo một chỉ thị rất đơn giản hiển thị cặp khóa/giá trị. Tôi muốn có thể tự động ẩn phần tử nếu nội dung được chuyển đổi bị trống (độ dài bằng không hoặc chỉ khoảng trắng).Làm cách nào để ẩn phần tử nếu nội dung được nhúng bị trống?

Tôi không thể tìm ra cách truy cập nội dung được chuyển đổi từ trong chỉ thị.

app.directive('pair', function($compile) { 
    return { 
    replace: true, 
    restrict: 'E', 
    scope: { 
     label: '@' 
    }, 
    transclude: true, 
    template: "<div><span>{{label}}</span><span ng-transclude></span></div>" 
    } 
}); 

Ví dụ: tôi muốn phần tử sau được hiển thị.

<pair label="My Label">Hi there</pair> 

Nhưng hai yếu tố tiếp theo phải được ẩn vì chúng không chứa bất kỳ nội dung văn bản nào.

<pair label="My Label"></pair> 
<pair label="My Label"><i></i></pair> 

Tôi mới đến Angular nên có thể có cách xử lý tuyệt vời thứ này. Bất kỳ trợ giúp được đánh giá cao.

Trả lời

8

Đây là cách tiếp cận sử dụng ng-show trên mẫu và trong vòng compile transcludeFn kiểm tra xem html được nhúng có độ dài văn bản hay không.

Nếu không có độ dài văn bản ng-show được thiết lập để ẩn

app.directive('pair', function($timeout) { 
    return { 
    replace: true, 
    restrict: 'E', 
    scope: { 
     label: '@' 
    }, 
    transclude: true, 
    template: "<div ng-show='1'><span>{{label}} </span><span ng-transclude></span></div>", 
    compile: function(elem, attrs, transcludeFn) { 
      transcludeFn(elem, function(clone) { 
       /* clone is element containing html that will be transcludded*/ 
       var show=clone.text().length?'1':'0' 
       attrs.ngShow=show; 
      }); 
     } 
    } 
}); 

Plunker demo

+1

+1 cho bất kỳ câu trả lời nào cho thấy trường hợp sử dụng cho transcludeFn bí truyền :). –

+1

trong transcludeFn, 'clone.text(). Trim(). Length' sẽ chính xác hơn một chút – alalonde

+0

+1 cảm ơn, điều này vừa tiết kiệm cho tôi rất nhiều thời gian. – cgTag

0

Tôi không quen thuộc lắm với transclude nên không chắc liệu nó có giúp ích hay không.

nhưng một cách để kiểm tra nội dung trống bên trong mã chỉ thị là sử dụng đối tượng iElement.text() hoặc iElement.context rồi ẩn nó.

+0

Cảm ơn. Tôi thực sự đã cố gắng làm điều đó trong hàm 'link', nhưng nội dung vẫn chưa được chuyển đổi qua điểm đó. – jessegavin

0

tôi đã làm nó như thế này, sử dụng controllerAs.

/* bên trong chỉ thị */

  controllerAs: "my", 
controller: function ($scope, $element, $attrs, $transclude) { 
//whatever controller does 
}, 
     compile: function(elem, attrs, transcludeFn) { 
        var self = this; 
        transcludeFn(elem, function(clone) { 
         /* clone is element containing html that will be transcluded*/ 
         var showTransclude = clone.text().trim().length ? true : false; 
         /* I set a property on my controller's prototype indicating whether or not to show the div that is ng-transclude in my template */ 
         self.controller.prototype.showTransclude = showTransclude; 
        }); 
       } 

/* bên trong mẫu */

<div ng-if="my.showTransclude" ng-transclude class="tilegroup-header-trans"></div> 
1

Những câu trả lời cung cấp lúc trước là hữu ích nhưng không giải quyết tình huống của tôi hoàn hảo, vì vậy tôi đã đưa ra một giải pháp khác bằng cách tạo ra một chỉ thị riêng biệt.

Tạo chỉ thị dựa trên thuộc tính (ví dụ: restrict: 'A') chỉ cần kiểm tra xem liệu có bất kỳ văn bản nào trên tất cả các nút con của phần tử hay không.

function hideEmpty() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attr) { 
      let hasText = false; 

      // Only checks 1 level deep; can be optimized 
      element.children().forEach((child) => { 
       hasText = hasText || !!child.text().trim().length; 
      }); 

      if (!hasText) { 
       element.attr('style', 'display: none;'); 
      } 
     } 
    }; 
} 

angular 
    .module('directives.hideEmpty', []) 
    .directive('hideEmpty', hideEmpty); 

Nếu bạn chỉ muốn kiểm tra các yếu tố chính:

link: function (scope, element, attr) { 
    if (!element.text().trim().length) { 
     element.attr('style', 'display: none;'); 
    } 
} 

Để giải quyết vấn đề của tôi, tất cả tôi cần là để kiểm tra xem có bất kỳ nút con:

link: function (scope, element, attr) { 
    if (!element.children().length) { 
     element.attr('style', 'display: none;'); 
    } 
} 

YMMV

1

Nếu bạn không muốn sử dụng ng-show mỗi lần, bạn có thể tạo chỉ thị để tự động hiển thị:

.directive('hideEmpty', ['$timeout', function($timeout) { 

    return { 
     restrict: 'A', 

     link: { 
      post: function (scope, elem, attrs) { 
       $timeout(function() { 
        if (!elem.html().trim().length) { 
         elem.hide(); 
        } 
       }); 
      } 
     } 
    }; 

}]); 

Sau đó, bạn có thể áp dụng nó trên bất kỳ phần tử nào. Trong trường hợp của bạn, nó sẽ là:

<span hide-empty>{{label}}</span> 
2

Có thể hơi muộn nhưng bạn cũng có thể xem xét sử dụng lớp CSS giả: trống. Vì vậy, điều này sẽ làm việc (IE9 +)

.trancluded-item:empty { 
    display: none; 
} 

Yếu tố vẫn sẽ được đăng ký trong dom nhưng sẽ được bỏ trống và vô hình.

Các vấn đề liên quan