在ngAnimateSwap中使用它自己的控制器的指令导致在每个交换机上初始化新的控制器'

时间:2016-06-23 16:49:40

标签: angularjs angularjs-directive ng-animate angularjs-controlleras isolate-scope

我创建了一个指令(ParentDir),它有自己的控制器,其模板绑定到该控制器。它与另一个指令(Child1)进行通信,该指令具有它自己的控制器,该控制器需要'第一个父指令。以下是一个简化示例:

Module.directive("ParentDir", function () {
 return {
    templateUrl: '../ParentTemplate',
    restrict: 'AEC',
    scope: {       
        },
    controllerAs: 'parCtrl',
    bindToController: true,
    controller: ['$scope', function ($scope) {
        parCtrl= this;
        parCtrl.title = "PARENT 1 TITLE";
      }]}


 Module.directive("Child1", function () {
return {
    templateUrl: '../Child1Template',
    restrict: 'AEC',
    require: '^^ParentDir',
    scope: {},
    controllerAs: 'ch1Ctrl',
    bindToController: true,

    link: function ($scope, element, attrs, parCtrl) {
        $scope.parCtrl= parCtrl;
    },

    controller: ['$scope', function ($scope) {
           ch1Ctrl= this;
           ch1Ctrl.title = "CHILD 1 TITLE";
 }]}

ParentDir html:

     <child1> </child1>

Child1 html:

  {{parCtrl.title}}
  {{ch1Ctrl.title}}

最后,我的ParentDirective初始化为:

  <div ng-animate-swap="trigger" class="swapclass">
         <parent-dir></parent-dir>
   </div>

我需要在某些情况下滑动整个父指令的模板。我也在其他我不需要的地方使用该指令,我可以按原样使用它。在我确实需要幻灯片动画的情况下,我将它放在ng-animate-swap中,如上所示。问题是每次交换触发器改变时,都会初始化一个新的parCtrl,导致所有内容都被重置!

如何使用具有隔离范围的指令和它自己的控制器进行动画交换,而不是每次发生交换时都重新初始化控制器?

1 个答案:

答案 0 :(得分:1)

正如我们所知,指令是高级标记,它告诉Angular的编译器将指定的行为附加到该HTML元素。当一个指令放在DOM上时,Angular的$compile服务将指令名称与其代码匹配,对其进行规范化并执行它。

但是,ng-animate-swap 会在添加新元素之前从DOM中删除元素。

这意味着每个交换都会重新编译您的指令,并且每次动画发生时都会创建新的隔离范围。

解决方案取决于您的应用程序的功能,模板的大小,以及您需要动画的频率(或动画所需的内容):

一种解决方案是在交换动画之外创建另一个指令,该指令包含parCtrl.titlech1Ctrl.title(或您拥有的任何其他变量),然后能够通过原型将该信息传递到子范围继承性:

    <swap-dir>
      <div ng-animate-swap="trigger" class="swapclass">
        <parent-dir></parent-dir>
      </div>
    <swap-dir>

这也可以通过控制器完成,也许更容易。您选择做什么将取决于您从哪里获取范围变量以及您在页面上有多少不同的元素。

然而,ng-animate-swap创建了自己的范围,所以虽然我相信这会有效,但是有趣的JavaScript继承恶作剧也可能会引起问题。

另一个解决方案是完全跳过ng-animate-swap并使用常规的旧CSS过渡动画模板元素,尽管这取决于你正在做什么以及你希望它看起来如何。