5

I want to access the scope of a transcluded element the VERY first time it is inserted in the tag in a directive with isolated scope. I have access to the clones of the transcluded element using the transclude function, but not for the very first time the element is inserted.

I have the following HTML

<my-directive the-name="'John Doe'">
   <my-div name="myDivName"></my-div>
</my-directive>

I have two directives. I want to transclude the contents of my-directive and be able to access a variable called "myDivName" from the scope created for the transcluded element. That variable gets its contents from the variable "theName" in the isolated scope of the "my-directive" directive.

This is my Javascript code:

var app = angular.module('test', []);
    app.directive('myDirective', function(){
      return {
        restrict: 'E',
        template: '',
        transclude: true,
        scope:{
          theName: '='
        },
        template: '<div>Hello I am My Directive and this content goes BEFORE the transclude<br><ng-transclude></ng-transclude><p>This element goes after the transclude</p></div>',
        link: function(scope, element, attrs, ctrl, transclude){
          transclude(function (clone, transcludeScope) {
          transcludeScope.myDivName = scope.theName;
          element.append(clone);//This line shouldn't be here. I just put it to illustrate that this clone has the right value in the output.
        });
        }
      }
    });
    app.directive('myDiv', function(){
      return {
        restrict: 'E',
        scope: {
          name: '='
        },
        template: '<div>{{name}}</div>'
      }
    });

As you can see I use the transclude parameter of the link function in "my-directive" directive to set the right value for the variable "myDivName" in the transcluded scope. However that code only executes AFTER Javascript has replaced the contents in the tag in "my-directive" and allows me to append as man clones of the transcluded contents as I want (I have access to their scopes so there's no problem).

HTML of the Output

<html>
<head>
</head>
<body ng-app="test" class="ng-scope">
<my-directive the-name="'John Doe'" class="ng-isolate-scope">
  <div>Hello I am My Directive and this content goes BEFORE the transclude<br>
  <ng-transclude>
    <!-- This is the very first time the transcluded element is inserted. 
    I want access to its scope just like I have access to the clone's scope in the transclude function. -->
    <my-div name="myDivName" class="ng-scope ng-isolate-scope">
      <div class="ng-binding">
      </div>
    </my-div>
  </ng-transclude>

  <p>This element goes after the transclude</p></div>
  <!-- This is a clone which scope was correctly modified to set the variable -->
  <my-div name="myDivName" class="ng-scope ng-isolate-scope">
    <div class="ng-binding">John Doe</div></my-div>
  </my-directive>    
</body>
</html>

The problem is the contents inserted the very first time in the tag in "my-directive". How do I access the scope of that very first transcluded clone?

There's an "easy way" of doing it, and it is to expose the variable of the isolated scope of "my-directive" like this post suggests ngModel needs $parent when within Transcluded html , but I don't want to crowd the parent scope of "my-directive" with such variables.

4

1 回答 1

0

我建议不要在您的模板中使用 ngTransclude。ngTransclude 链接到预隔离范围(包含范围),您是对的 - 您无权访问它。

相反,使用 transclude 函数,并自己插入克隆:

template: '<div>Hello I am My Directive and this content goes BEFORE the transclude<br><insert-here></insert-here><p>This element goes after the transclude</p></div>',
link: function(scope, element, attrs, ctrl, transclude){
  transclude(function (clone, transcludeScope) {
  transcludeScope.myDivName = scope.theName;
  var e = element.find('insert-here');
  e.append(clone);        
});

如果你真的想要 ngTransclude

或者,如果您真的希望 ngTransclude 在您的模板中,那么以下应该可以工作:

template: '<div>Hello I am My Directive and this content goes BEFORE the transclude<br><ng-transclude></ng-transclude><p>This element goes after the transclude</p></div>',
link: function(scope, element, attrs, ctrl, transclude){
  var e = element.find('ng-transclude');
  transcludeScope = e.scope();
  transcludeScope.myDivName = scope.theName;

});

这个解决方案是使用jqLit​​e找到ngTransclude,然后调用scope()方法得到transclusion作用域。

于 2015-10-22T12:41:11.723 回答