2

我有一个非常简单的设置:

<pane title="mytitle">Title in parent (transcluded): {{title}}</pane>

angular.module('transclude', [])
 .directive('pane', function(){
    return {
      restrict: 'E',
      transclude: true,
      scope: { title:'@' },
      template: '<div>' +
                  '<div>Title in isolated scope: {{title}}</div>' +
                  '<div ng-transclude></div>' +
                '</div>'
    };
});

plunker 在这里:http ://plnkr.co/edit/yRHcNGjQAq1NHDTuwXku

嵌入本身正在工作,但{{title}}唯一在指令的模板中被替换。然而,即使指令在其范围内有一个变量,被嵌入元素
的内部仍然是空的。这是为什么?{{title}}title

4

2 回答 2

3

被嵌入元素的范围不是指令的子范围,而是同级范围。这就是文档所说的:

在典型的设置中,小部件创建了一个隔离范围,但嵌入不是子范围,而是隔离范围的兄弟。

在这种情况下,如何访问 transcded 范围的最简单解决方案如下:

.directive('pane', function () {
    return {
        restrict: 'E',
        transclude: true,
        scope: {
            title: '@'
        },
        template:
            '<div>' +
                '<div>Title in isolated scope: {{title}}</div>' +
                '<div ng-transclude></div>' +
            '</div>',
        link: function (scope, element, attrs) {
            scope.$$nextSibling.title = attrs.title;
        }
    };
});

演示:http ://plnkr.co/edit/ouq9B4F2qFPh557708Q1?p=preview

于 2014-04-12T08:01:44.343 回答
2

@dfsq 是正确的:

被嵌入元素的作用域不是指令的子作用域,而是同级作用域

我想添加更多评论,为什么这是 angularJs 的预期行为。正如文档所说:

在典型的设置中,小部件创建了一个隔离范围,但嵌入不是子范围,而是隔离范围的兄弟。这使得小部件可以拥有私有状态,并且嵌入可以绑定到父(预隔离)范围。

指令内的嵌入内容是任意的,它不应该知道指令的隔离范围,否则我们会创建一个紧密耦合的代码。因为要使嵌入的内容起作用,内容必须知道您的指令的实现细节(可以使用什么)。

如果您决定内容属于该指令。您有 2 个选项:

1)使内容成为模板的一部分

    angular.module('transclude', [])
         .directive('pane', function(){
            return {
              restrict: 'E',
              transclude: true,
              scope: { title:'@' },
              template: '<div>' +
                          '<div>Title in isolated scope: {{title}}</div>' +
                          '<div>' +
                             ' Title in parent (transcluded): {{title}} ' +
                         ' </div>' +
                        '</div>'
            };
   });

演示

2)使用自定义嵌入自己绑定范围:

angular.module('transclude', [])
     .directive('pane', function(){
        return {
          restrict: 'E',
          transclude: true,
          scope: { title:'@' },
          template: '<div>' +
                      '<div>Title in isolated scope: {{title}}</div>' +
                      '<div class="transclude"></div>' +
                    '</div>',
        link: function (scope, element, attr,controller, linker) {
           linker(scope, function(clone){
                  element.find(".transclude").append(clone); // add to DOM
           });
          }
        };
    });

演示

于 2014-04-12T08:57:01.250 回答