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

时间:2013-12-03 16:55:39

标签: javascript html angularjs angularjs-directive

我正在尝试使用如下所示的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>'
            ...
        }
    })

1 个答案:

答案 0 :(得分:2)

这是一个非常简单的选择,但你可以通过很多方式来实现它。

我不认为可以在不降低动态的情况下使用模板。换句话说,您的父“mySplitter”指令可以始终创建相同的标记,它会没问题,但是如果您想为其添加更多myPane,那么每个mySplitter模板都必须更改时间。我的解决方案简单,易于阅读和动态(添加任意数量的窗格,他们将获得分隔符。)

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

Live demo here (click).

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>'
  };
});

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