你能在 Angular 中嵌入一个子指令吗?

Can you transclude into a child directive in Angular?

我希望能够在我的应用程序中执行类似的操作:

<pill-autocomplete>
  <pill-template>{{item.name}}</pill-template>
</pill-autocomplete>

其中 pill-autocomplete 有一个模板可以像这样嵌入到子指令中:

<pills ng-transclude="pillTemplate"></pills>
<input type="text">

鉴于 ng-transclude 创建作用域并且 <pills> 指令具有隔离作用域,这似乎是不可能的。

我想到的一种实现方法是在自动完成的模板函数中注入 pill 模板。问题在于它失去了包含范围。我还必须在每个与药丸具有相似行为的指令中执行此操作。

在 angular 1.x 中还有其他方法可以实现吗?

这是一种可能将数据输入 child DDO 的方法。如果有任何不清楚的地方,请告诉我,希望对您有所帮助。

function exampleController($scope) {
  $scope.data = [
    'cupidatat',
    'laboris',
    'minim',
    'nisi',
    'anim',
    'id',
    'laboris'
  ];
}

function exampleParentDirective() {
  return {
    restrict: 'E',
    scope: {
      data: '='
    },
    template: '<div class="parent-example"></div>'
      //optionally you could potentially use the child
      //directive in the template of this DDO.
      //template: '<div class="parent-example"><example-directive data="data"></example-directive></div>'
  };
}

function exampleDirective() {
  return {
    restrict: 'E',
    scope: {
      data: '='
    },
    template: '<div class="child-example" ng-repeat="ipsum in data track by $index" ng-bind="ipsum"></div>',
    link: function($scope) {
      //link function not need unless you need other processing done in child directive.
    }
  };
}

angular
  .module('app', [])
  .controller('exampleController', exampleController)
  .directive('exampleParentDirective', exampleParentDirective)
  .directive('exampleDirective', exampleDirective);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="app">
  <div class="row" ng-controller="exampleController">
    <example-parent-directive data="data"></example-parent-directive>
    <example-directive data="data"></example-directive>
  </div>
</div>

这个演示可能有帮助
https://docs.angularjs.org/guide/directive

index.html

 <my-tabs>
  <my-pane title="Hello">
    <p>Lorem ipsum dolor sit amet</p>
  </my-pane>
  <my-pane title="World">
    <em>Mauris elementum elementum enim at suscipit.</em>
    <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
  </my-pane>
</my-tabs>

我的-tabs.html

<div class="tabbable">
  <ul class="nav nav-tabs">
    <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
      <a href="" ng-click="select(pane)">{{pane.title}}</a>
    </li>
  </ul>
  <div class="tab-content" ng-transclude></div>
</div>

我的-pane.html

<div class="tab-pane" ng-show="selected">
  <h4>{{title}}</h4>
  <div ng-transclude></div>
</div>

当然 script.js

angular.module('docsTabsExample', [])
.directive('myTabs', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    controller: ['$scope', function MyTabsController($scope) {
      var panes = $scope.panes = [];

      $scope.select = function(pane) {
        angular.forEach(panes, function(pane) {
          pane.selected = false;
        });
        pane.selected = true;
      };

      this.addPane = function(pane) {
        if (panes.length === 0) {
          $scope.select(pane);
        }
        panes.push(pane);
      };
    }],
    templateUrl: 'my-tabs.html'
  };
})
.directive('myPane', function() {
  return {
    require: '^^myTabs',
    restrict: 'E',
    transclude: true,
    scope: {
      title: '@'
    },
    link: function(scope, element, attrs, tabsCtrl) {
      tabsCtrl.addPane(scope);
    },
    templateUrl: 'my-pane.html'
  };
});

问题是,当您将数据从 pill-autocomplete 转入 pills 时,您已经删除了 pills 中的内容。

嵌入替换了指令模板下的内容,因此 pills 指令模板中的内容根本无法加载,因为已被嵌入覆盖。

我的建议很简单,不要直接使用里面有 ng-transclude 的标签,使用一个内部的 div 来让指令加载它的内容成为可能

angular.module('app', []);
  var app = angular.module('app');

  'use strict';

  var app =  angular.module('app');

  app.controller('testController', [
    function () {
      var vm = this;
      vm.name = 'Jimmy';
    }]);

  app.directive('pillAutocomplete', function () {
    return {
      priority: 100,
      restrict: 'E',
      transclude: true,
      template: '<pills><p>From Pill-Autocomplete</p><div ng-transclude><div></pills>'
    };
  });

  app.directive('pills', function () {
    return {
      restrict: 'E',
      transclude: true,
      link: function (scope, element, attrs) {
        scope.style = true;
      },
      template: '<p>Inside Pills</p><div ng-class="{pillscolor : style}" ng-transclude></div>'
    };
  });
.pillscolor{
  color: green;
  font-size: 20px;
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<article ng-app="app">
<section ng-controller="testController as test">
 Controller scope - {{test.name}}
  <pill-autocomplete>
     From controller - {{test.name}}
  </pill-autocomplete>
</section>
</article>