2014-05-21 56 views
1

使用Angular 1.2.9(寫作時最新的穩定版)。一個指令,顯示了問題的小例子:如何結合transclusion,replace和ngIf?

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也使用transclusion有關。

我不確定這是否是一個角度錯誤,或者我是否做錯了什麼。

我能想到的一些解決方法的:

  • 刪除ng-if和手動執行它的行爲。但是它的實現有幾十行,我不能很好地重現它的信心。
  • 停止使用替換,停止使用模板,並在指令的元素本身上設置所有需要的樣式和類。這需要一堆JavaScript代碼來重現代碼中的模板結構。

約束上的任何解決方案/解決方法:

  • 因爲我使用的是Flexbox的,生成的元素必須是指令的父元素直接子(即什麼代替呢)。
  • ngIf不能移動到指令之外,因爲實際上我使用的是依賴於指令的隔離範圍的條件。

有沒有更好的方法來使這個工作?

回答

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的相應方法。

+0

我終於和'ng-show'一起去了。如果性能問題成爲問題,我總是可以重新訪問。 – Thomas