与Transclude元素一起,我可以将其范围传递给指令吗?

时间:2016-07-17 12:50:57

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-transclude

当下我觉得我对Transclude的理解已经足够了解我发现了这句话:

Transclude allows us to pass in an entire template, including its scope, to a directive. 
Doing so gives us the opportunity to pass in arbitrary content and arbitrary scope to a directive.

这是否意味着,如果Transclude元素附加了一个范围并且它可以传递给指令?如果那是真的那么我就无法在指令模板中访问该范围属性。

让我先回过头来解释一下我们要做什么的代码:

JSFiddle Link

我的指令是directive-boxtransclude: true在指令定义对象(DDO)中定义。

现在有一个Child Div,它是 Transcluded

的元素
<div ng-controller='TransCtrl'>Inside Transclude Scope : {{name}}</div>

并附加了控制器TransCtrl

现在我尝试在DDO中定义此属性后,从指令级别访问属于$scope.name的{​​{1}}属性:

TransCtrl

这可能吗?

这更像是尝试访问子范围属性的父范围,这是否允许在JavaScript原型继承中使用?或者还有其他我需要知道的东西吗?

如果这不可能,第一个陈述是什么意思?

scope: {
        title: '@directiveTitle',
        name: '='
      }

更新1:

我主要担心的是Controller应该保留Transclude元素,我们仍然可以将其(Transclude元素)范围传递给Directive,然后Directive应该能够使用该范围,即Transclude allows us to pass in an entire template, including its scope, to a directive.

name from TransCtrl controller

上面的代码行应保持不变。

我的问题可能完全错了,但如果可以完成,请告诉我。

2 个答案:

答案 0 :(得分:0)

这是否回答了您的问题:https://jsfiddle.net/marssfa4/4/

在其中我在外部创建了一个新的控制器(在指令中有效地替换了rootScope的功能)并且我在控制器模板中设置了指令的控制器。

虽然你可以看到它可以将html及其范围转换为具有自己范围的指令,但它的长短不一。

html:

<div ng-app='myApp' ng-controller="OutsideScope">
  <h1>{{externalWorld}}</h1>
  <div directive-box directive-title='{{directiveWorld}}' name='name'>
    <div>Inside Transclude Scope : {{name}}</div>
  </div>
</div>

JS(包括Update 1):

angular.module('myApp', [])
  .directive('directiveBox', function() {
    return {
      restrict: 'EA',
      scope: {
        title: '@directiveTitle',
        name: '='
      },
      transclude: true,
      template: '<div ng-controller="TransCtrl">\
        <h2 class="header">{{ title }}</h2>\
                <div class="dirContent">Directive Element</div>\
                <div>Outside Transclude Scope : {{name}}</div>\
                <div class="content" ng-transclude></div>\
            </div>'
    }
  })
  .controller('TransCtrl', function($scope) {
    $scope.name = 'Transclude World'
  })
  .controller('OutsideScope', function($scope) {
    $scope.name = 'External World'
  })
  .run(function($rootScope) {
    $rootScope.externalWorld = 'External World',
      $rootScope.directiveWorld = 'Here comes directive'
  });

更新1:JSFIDDLE

我恢复了原始范围声明,因为scope: false是一个错误。

如果我正确理解你的评论,你想让控制器留在要被转换的元素上,但仍然在该元素中有{{name}}忽略它的直接控制器并将其作为控制器使用它的父(即指令)范围。

我将控制器放在模板指令中的原因是因为这是限制指令范围而不是其转换元素的唯一方法。如果您明确地将控制器放在元素上,那么无论它是否包含在具有另一个范围的指令中,其最接近的范围都将覆盖在该指令上声明的任何范围。换句话说,无论指令的范围是什么,

中的{{name}}

<div ng-controller='TransCtrl'>Inside Transclude Scope : {{name}}</div>

始终是$scope.name中的TransCtrl

答案 1 :(得分:0)

问题似乎与在ng-transcluded html中定义控制器的方式有关。

我使用

更清楚了
  1. bindToController构造
  2. 在指令级使用控制器
  3. 请参阅this小提琴,了解一个工作示例。

    controllerAs: "TransCtrl",
    bindToController: true
    

    您的声明,&#39;父范围试图访问子范围属性&#39;是不对的?因为我们正在尝试使用父范围属性,即子视图中的名称(ng-transcluded content),这可能是典型继承,而不是相反。