如何结合transclusion,replace和ngIf?

时间:2014-05-21 14:00:05

标签: javascript angularjs

使用Angular 1.2.9(撰写本文时最新的稳定版)。显示问题的指令的最小示例:

myApp.directive('panel', function() {
    return {
        transclude: true,
        replace: true,
        template: '<div ng-if="showPanel" ng-transclude></div>',
    };
});

jsFiddle:http://jsfiddle.net/HB7LU/3782/打开控制台并切换复选框。它抱怨孤儿ngTransclude。据我所知,这与ngIf也使用翻译的事实有关。

我不确定这是一个角色错误还是我做错了什么。

我可以想到一些解决方法:

  • 删除ng-if并手动执行其行为。但它的实施是几十行,我不能很好地理解它,以充满信心地重现它。
  • 停止使用替换,停止使用模板,并在指令元素本身上设置所有需要的样式和类。这需要一堆JavaScript代码来重现模板的代码结构。

任何解决方案/解决方法的限制:

  • 因为我使用的是flexbox,所以生成的元素必须是指令父元素的直接子元素(即替换的元素)。
  • ngIf不能移到指令之外,因为实际上我使用的条件依赖于指令的隔离范围。

有没有更好的方法让它正常工作?

1 个答案:

答案 0 :(得分:0)

最简单的方法是使用ng-show代替ng-if

如果由于某种原因,您绝对需要从DOM树中删除该元素,那么自定义解决方案并不难创建。 Transclusion只是一个简单的函数调用,其余部分归结为观察值并从DOM中添加/删除元素:

return {
    transclude: true,
    replace: true,
    scope: {
        showPanel: '='
    },
    template: '<div></div>',
    link: function(scope, element, attrs, controller, transclude) {
        var parent = element.parent(),
            insertAfter = angular.element(element[0].previousSibling);

        transclude(scope.$parent, function (clone) {    
           element.append(clone);
        });

        scope.$watch('showPanel', function(value) {
            if (value) {         
              $animate.enter(element, parent, insertAfter);  
            }
            else {
              $animate.leave(element);
            }
        });
    }
};

这是一个working fiddle。当然,你可能想根据自己的情况调整它。如果您不想要动画,只需使用angular.element

的相应方法