Odd behavior when using transclusion without cloning

时间:2015-07-31 19:35:12

标签: javascript angularjs directive angularjs-ng-transclude

While experimenting with transclusion a bit, I wanted to see if the transcluded directive, which requires a certain parent directive controller, will be able to find it after being transcluded under the required parent. The Directives i've used are the following: There is a ParentOfParent directive which has transclude:true. There is a directive Parent which is embedded into ParentOfParent directive template There is a Child directive which requires Parent controller, and is being transcluded by ParentOfParent to be a child of Parent directive.

    'use strict';
angular
    .module('angularlabApp', [
    'ngRoute',
])
    .config(function ($routeProvider) {
    $routeProvider
        .when('/', {
        templateUrl: 'main.html',
        controller: 'MainCtrl'
    })
        .otherwise({
        redirectTo: '/'
    });
});

'use strict';
angular.module('angularlabApp')
    .directive('parent', function () {
    return {
        controller: function () { },
        restrict: 'EA',
        link: function postLink(scope, element, attrs) {
            console.log('Parent Link');
        }
    };
});

'use strict';

angular.module('angularlabApp')
  .directive('parentOfParent', function () {
    return {
      template: '<div id="prnt" parent></div>',
      transclude: true,
      restrict: 'EA',
      link: function(scope, element, attrs,_,transcludeFn){
        console.log('POP Link');
        element.find('#prnt').append(transcludeFn());

      }
    };
  });


'use strict';

angular.module('angularlabApp')
  .directive('child', function () {
    return {
      template: '<div></div>',
      restrict: 'EA',
      require:'^parent',
      link: function postLink(scope, element, attrs) {
        console.log('Child Link');
      }
    };
  });


'use strict';
angular.module('angularlabApp')
    .controller('MainCtrl', function ($scope) {
});

What i've encountered was an odd discrepancy between using transclusion function with and without cloning. When I am using the transclusion function output (without passing the cloneFn) I am getting an error that the child directive cant find Parent Controller above it. http://plnkr.co/edit/JteQpPMc6nbVNjRDHVZ2

However, when I am using it by passing cloneFn, everything works.

Is it even possible for transcluded directive to find required controller after being inserted below directive the controller belongs to?

1 个答案:

答案 0 :(得分:0)

感谢this回答和this文章,我终于明白了造成这种差异的原因。

当使用transclude函数的输出时(不传递克隆回调),输出已经编译并且 LINKED

var linkedClone = $transcludeFn();

由于链接已经发生,复制的指令已经查找了父指令的控制器。由于复制的DOM节点仍然是分离的,因此无法找到它。

相反,当通过克隆回调接收复制的DOM子树时,如文章中所述:

  

在指令范围的子范围内编译克隆并在调用其所有链接函数之前传递克隆

因此,您有机会在链接之前附加复制的DOM子树,从而允许它在DOM已经存在于DOM中时在其上方查找控制器。