我创建了一个非常简单的指令,它显示了一个键/值对。如果被转换的内容为空(零长度或只是空格),我希望能够自动隐藏元素。
我无法弄清楚如何访问从指令中转换的内容。
app.directive('pair', function($compile) {
return {
replace: true,
restrict: 'E',
scope: {
label: '@'
},
transclude: true,
template: "<div><span>{{label}}</span><span ng-transclude></span></div>"
}
});
例如,我希望显示以下元素。
<pair label="My Label">Hi there</pair>
但接下来的两个元素应该被隐藏,因为它们不包含任何文本内容。
<pair label="My Label"></pair>
<pair label="My Label"><i></i></pair>
我是Angular的新手,所以可能有一种很好的方法可以处理这种开箱即用的事情。任何帮助表示赞赏。
答案 0 :(得分:8)
以下是在模板上使用ng-show
并在compile transcludeFn
内检查转换后的html是否有文字长度的方法。
如果没有设置文字长度ng-show
来隐藏
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;
});
}
}
});
答案 1 :(得分:3)
也许有点晚了但你也可以考虑使用CSS Pseudo类:空。 所以,这将起作用(IE9 +)
.trancluded-item:empty {
display: none;
}
该元素仍将在dom中注册,但将为空且不可见。
答案 2 :(得分:1)
之前提供的答案很有帮助,但并没有完全解决我的情况,所以我通过创建一个单独的指令想出了一个不同的解决方案。
创建一个基于属性的指令(即restrict: 'A'
),只需检查所有元素的子节点上是否有任何文本。
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);
如果您只想查看主要元素:
link: function (scope, element, attr) {
if (!element.text().trim().length) {
element.attr('style', 'display: none;');
}
}
要解决我的问题,我需要的只是检查是否有任何子节点:
link: function (scope, element, attr) {
if (!element.children().length) {
element.attr('style', 'display: none;');
}
}
YMMV
答案 3 :(得分:1)
如果您不想每次都使用ng-show,您可以创建一个指令来自动执行:
.directive('hideEmpty', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: {
post: function (scope, elem, attrs) {
$timeout(function() {
if (!elem.html().trim().length) {
elem.hide();
}
});
}
}
};
}]);
然后你可以在任何元素上应用它。在你的情况下,它将是:
<span hide-empty>{{label}}</span>
答案 4 :(得分:0)
我对transclude并不十分熟悉,所以不确定它是否有帮助。
但检查指令代码中的空内容的一种方法是使用iElement.text()或iElement.context对象,然后将其隐藏。
答案 5 :(得分:0)
我是这样做的,使用controllerAs。
/ *指令内部* /
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;
});
}
模板内的/ * * /
<div ng-if="my.showTransclude" ng-transclude class="tilegroup-header-trans"></div>