AngularJS:在单个Angular指令中转换多个子元素

时间:2014-02-27 20:26:46

标签: angularjs angularjs-directive angularjs-scope

我对Angular很新,但已经阅读了很多。 我正在http://docs.angularjs.org/guide/directive#creating-custom-directives_demo_isolating-the-scope-of-a-directive阅读ng-transclude,我认为我理解它的作用。

如果您的指令适用于其中包含内容的元素,例如

<my-directive>directive content</my-directive>

它允许您使用ng-transclude标记指令模板中的元素,并且元素中包含的内容将在标记元素内呈现。

所以如果myDirective的模板是<div>before</div><div ng-transclude></div><div>after</div> 它将在之后呈现为先前的内容。

这都是o.k. 我的问题是,有可能以某种方式将一个html块传递给我的指令吗?

e.g。

假设指令用法如下:

<my-multipart-directive>
     <part1>content1</part1>
     <part2>content2</part2>
</my-multipart-directive>

并有一个模板:

<div>
  this: <div ng-transclude="part2"></div>
   was after that: <div ng-transclude="part1"></div>
   but now they are switched
<div>

渲染为

<div>
  this: <div ng-transclude="part2">content2</div>
   was after that: <div ng-transclude="part1">content1</div>
   but now they are switched
<div>

(以自己的想法)我可以以某种方式将节点的HTML值绑定到模型,这样我就可以以这种方式使用它,而无需将其称为“transclude”......

由于

3 个答案:

答案 0 :(得分:32)

启动Angular 1.5,现在可以创建多个插槽。您可以使用每个广告位的映射提供对象,而不是 transclude:true

https://docs.angularjs.org/api/ng/directive/ngTransclude

angular.module('multiSlotTranscludeExample', [])
 .directive('pane', function(){
    return {
      restrict: 'E',
      transclude: {
        'title': '?pane-title',
        'body': 'pane-body',
        'footer': '?pane-footer'
      },
      template: '<div style="border: 1px solid black;">' +
                  '<div class="title" ng-transclude="title">Fallback Title</div>' +
                  '<div ng-transclude="body"></div>' +
                  '<div class="footer" ng-transclude="footer">Fallback Footer</div>' +
                '</div>'
    };
})

答案 1 :(得分:21)

很酷的问题。我不确定是否有内置方式,但您可以通过非常通用的方式自行完成。

您可以通过传递$ transclude服务来访问transcluded元素,如下所示:

$transclude(function(clone, $scope) {

克隆将是预链接的已转换内容的副本。然后,如果您在元素中标记内容,如下所示:

    <div id="content">
        <div id="content0">{{text}}</div>
        <div id="content1">{{title}}</div>
    </div>

您可以遍历内容并按如下方式编译:

$scope.transcludes.push($compile(clone[1].children[i])($scope));

大!现在你只需要将内容放在模板中的正确位置

     '<div id="transclude0"></div>' +
     '<div id="transclude1"></div>' +

然后您可以在链接功能中正确分配内容

angular.element(document.querySelector('#transclude' + i)).append(scope.transcludes[i]);

我设置了一个fiddle你可以玩这个设置。

希望这有帮助!

答案 2 :(得分:1)

在我们的项目中,我们在JSF 2的ui:composition,ui:insert,ui:define(参见ui:composition)之后建模了多站点trasclusion。

实现包含三个简单的指令:ui-template,ui-insert,ui-define(参见angularjs-api/template/ui-lib.js)。

要定义模板,请编写以下标记(请参阅angularjs-api/template/my-page.html):

<table ui-template>
  <tr>
    <td ui-insert="menu"></td>
  </tr>
  <tr>
    <td ui-insert="content"></td>
  </tr>
</table>

并声明一个指令(参见angularjs-api/template/my-page.js):

  var myPage = 
  {
    templateUrl: "my-page.html",
    transclude: true
  };

  angular.module("app").
    directive("myPage", function() { return myPage; });

最后,要实例化需要编写的指令(参见angularjs-api/template/sample.html):

<my-page>
  <div ui-define="content">
    My content
  </div>
  <div ui-define="menu">
    <a href="#file">File</a>
    <a href="#edit">Edit</a>
    <a href="#view">View</a>
  </div>
</my-page>

可以通过rawgit看到工作样本:sample.html

另请参阅:Multisite Transclusion in AngularJS