Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 如果转包的内容为空,如何隐藏元素?_Angularjs_Angularjs Directive_Transclusion - Fatal编程技术网

Angularjs 如果转包的内容为空,如何隐藏元素?

Angularjs 如果转包的内容为空,如何隐藏元素?,angularjs,angularjs-directive,transclusion,Angularjs,Angularjs Directive,Transclusion,我创建了一个非常简单的指令,它显示一个键/值对。如果转写的内容为空(长度为零或仅为空白),我希望能够自动隐藏元素 我不知道如何访问从指令中转移的内容 app.directive('pair', function($compile) { return { replace: true, restrict: 'E', scope: { label: '@' }, transclude: true, template: "<div&g

我创建了一个非常简单的指令,它显示一个键/值对。如果转写的内容为空(长度为零或仅为空白),我希望能够自动隐藏元素

我不知道如何访问从指令中转移的内容

app.directive('pair', function($compile) {
  return {
    replace: true,
    restrict: 'E',
    scope: {
      label: '@'
    },
    transclude: true,
    template: "<div><span>{{label}}</span><span ng-transclude></span></div>"
  }
});
app.directive('pair',function($compile){
返回{
替换:正确,
限制:'E',
范围:{
标签:“@”
},
是的,
模板:“{label}}”
}
});
例如,我希望显示以下元素

<pair label="My Label">Hi there</pair>
你好 但是接下来的两个元素应该隐藏,因为它们不包含任何文本内容

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


我是个新手,所以可能会有一个很好的方法来处理这类事情。非常感谢您的帮助。

我对transclude不太熟悉,所以不确定它是否有用


但是检查指令代码中是否有空内容的一种方法是使用iElement.text()或iElement.context对象,然后将其隐藏。

这里有一种方法,在模板上和
编译transcludeFn
中使用
ng show
检查被转换的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;
            });
        }
  }
});
app.directive('pair',function($timeout){
返回{
替换:正确,
限制:'E',
范围:{
标签:“@”
},
是的,
模板:“{label}}”,
编译:函数(elem、attrs、transcludeFn){
transcludeFn(元素,函数(克隆){
/*克隆是包含将被转包的html的元素*/
var show=clone.text()。长度?'1':'0'
attrs.ngShow=show;
});
}
}
});

我是这样做的,使用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>

前面提供的答案很有帮助,但并不能完美地解决我的问题,因此我通过创建一个单独的指令,想出了一个不同的解决方案

app.directive('pair', function($compile) {
  return {
    replace: true,
    restrict: 'E',
    scope: {
      label: '@'
    },
    transclude: true,
    template: "<div><span>{{label}}</span><span ng-transclude></span></div>"
  }
});
创建一个基于属性的指令(即
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

如果您不想每次都使用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>
{{label}

> p>可能有点晚,但您也可以考虑使用CSS伪类:空。 因此,这将起作用(IE9+)


元素仍将在dom中注册,但将为空且不可见。

谢谢。实际上,我在
link
函数中尝试过这样做,但到那时,内容还没有被排除。+1对于任何显示深奥transcludeFn用例的答案:)。在transcludeFn中,
clone.text().trim().length
会更精确一些这非常优雅,也适用于非angularjs应用程序。