繁体   English   中英

Angularjs指令,在transcluded内容中包含元素

[英]Angularjs directive with element in the middle of transcluded content

我正在尝试使用angularjs创建一个splitter指令,如下所示:

<my-splitter>
  <my-pane1>Pane 1</my-pane1>
  <my-pane2>Pane 2</my-pane2>
</my-splitter>

我希望这样做:

<div class="splitter">
  <div class="splitter-pane1">Pane 1</div>
  <div class="splitter-handle"></div>
  <div class="splitter-pane2">Pane 2</div>
</div>

问题是我想把处理程序放在两个窗格的中间,但我不知道如何使用ng-transclude来完成它。 这是js:

angular.module('myModule', [])
    .directive('mySplitter', function() {
        return {
            restrict: 'E',
            replace: true,
            transclude: true,
            template: 'how do i put the handler in the middle of the two panes?'
            ...
        }
    })
    .directive('myPane1', function () {
        return {
            restrict: 'E',
            require: '^mySplitter',
            replace: true,
            transclude: true,
            template: '<div class="split-pane1" ng-transclude><div>'
            ...
        }
    })
    .directive('myPane2', function () {
        return {
            restrict: 'E',
            require: '^mySplitter',
            replace: true,
            transclude: true,
            template: '<div class="split-pane2" ng-transclude><div>'
            ...
        }
    })

这是一个非常简单的选择,但有很多方法可以做到。

我不认为可以使用模板完成而不会降低动态。 换句话说,你的父“mySplitter”指令总是可以创建相同的标记,它会没问题,但是如果你想为它添加更多的myPane ,那么mySplitter都需要更改mySplitter模板。 我的解决方案简单,易于阅读和动态(添加任意数量的窗格,他们将得到一个分隔符)。

对于窗格,棘手的部分是你似乎希望它们在类名中编号。 我不知道为什么你需要那个(我怀疑你真的这么做),但我为此提供了一个解决方案。 您使用指令的每次运行都可以看到的变量,但只初始化一次。 有一个范围,指令的所有运行都可以看到(注意我在哪里创建变量count ,然后link函数可以访问它,但该函数运行指令的每次使用,所以每次你可以增加它,设置count以下指令使用。

现场演示(点击)。

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

app.directive('mySplitter', function($compile) {
  return {
    restrict: 'EA',
    link: function(scope, element, attrs) {
      var children = element.children();
      angular.forEach(children, function(elem, i) {
        if (i < children.length-1) {
          var splitter = angular.element('<div class="splitter-handle">Class is: splitter-handle</div>');
          var child = angular.element(elem);
          child.after(splitter);
        }
      });
    }
  };
});

app.directive('myPane', function() {
  var count = 1; //this runs only once
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    scope: {},
    template: '<div class="splitter-pane{{count}}" ng-transclude>Class is: splitter-pane{{count}}</div>',
    link: function(scope, element) { 
      //this runs for each use of "myPane"
      scope.count = count.toString(); //convert to string or there will be an error
      ++count; //increment the count for the next item
    }
  };
});

为了澄清“动态”和“非动态”的含义,如果你只需要两个面板划分,你可以这样做:

app.directive('mySplitter', function($compile) {
  return {
    restrict: 'EA',
    replace: true,
    template:
      '<div class="splitter">'+
        '<div class="splitter-pane1">Pane 1</div>'+
        '<div class="splitter-handle"></div>'+
        '<div class="splitter-pane2">Pane 2</div>'+
      '</div>'
  };
});

显然,另一种方法更灵活。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM