当角元素的孩子完成链接时运行脚本

时间:2014-10-09 17:03:13

标签: javascript jquery angularjs

我想知道构建这个简单的angularJS场景的最佳方法。

我有一个<div>,其中包含另外两个<div>。当DOM准备就绪时,我使用jQuery splitter plugin使两个孩子变得相当大。

在普通的旧HTML中,这没问题!它看起来像这样:

    <div id="container">
        <div id="leftPane">...</div>
        <div id="rightPane">...</div>
    </div>

    <script>
    $('#container').split('horizontal');
    </script>

现在我想将组件转换为AngularJS指令,而我遇到了一个问题。这是根HTML模板:

    <div id="container" ng-controller="containerCtrl">
        <left-pane></left-pane>
        <right-pane></right-pane>
    </div>

leftPanerightPane的指令类似于:

app.directive('leftPane', function(){
  return {
    templateUrl: 'leftPane.html',
    replace: true
  }
});

使用leftPane.html

<div id="leftPane"></div>

容器控制器:

app.controller('containerCtrl', ['$scope', function($scope){
    $('#container').split('horizontal');
}]);

问题是,在.split()调用发生时,子面板尚未编译和评估。

我应该在何处/如何调用.split()以确保孩子们已经过评估并且正确地在DOM中?


***更新:以下是一个展示问题的Plunker:http://plnkr.co/edit/idODF0ztbqip44rfsZsE?p=preview

有趣的是,使用文字模板(template:'<div>left panel</div>')时没有问题。使用templateUrl时会出现此问题。我猜templateUrl的评估顺序不同吗?

告诉正在发生的事情的最简单方法是在调整拆分器大小时查看DOM。您可以看到插件动态设置width。但它没有附在左侧面板上。在初始化插件时,左窗格尚未添加到DOM中。

2 个答案:

答案 0 :(得分:3)

请注意,在创建并链接所有子项后,link函数(与controller创建不同)称为。因此,只需将您的拆分器代码放在父指令的link函数中。

有关执行顺序的更多信息,请考虑this very helpful blog post。向下滚动到&#34;但为什么?!?&#34;,你会发现:

parent (compile)
..child 1 (compile)
....child 1 a (compile)
....child 1 b (compile)
..child 2 (compile)
....child 2 a (compile)
....child 2 b (compile)
parent (controller)
parent (pre-link)
..child 1 (controller)
..child 1 (pre-link)
....child 1 a (controller)
....child 1 a (pre-link)
....child 1 a (post-link)
....child 1 b (controller)
....child 1 b (pre-link)
....child 1 b (post-link)
..child 1 (post-link)
..child 2 (controller)
..child 2 (pre-link)
....child 2 a (controller)
....child 2 a (pre-link)
....child 2 a (post-link)
....child 2 b (controller)
....child 2 b (pre-link)
....child 2 b (post-link)
..child 2 (post-link)
parent (post-link)

(请注意 post-link 与默认link相同。)

<强>更新

您正在为容器元素使用控制器。相反,将它改为指令,一切都会好的!

答案 1 :(得分:1)

如果我是你,我会反过来做,就像这样:

查看:

<div my-splitter="vertical" class="container">
  <left-pane my-splitter-split></left-pane>
  <right-pane></right-pane>
</div>

指令:

app.directive('mySplitter', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs, ctrl) {
      ctrl.orientation=attrs.mySplitter;
    },
    controller: function($element){
      this.split = function(){
        var orientation= this.orientation;
        $element.split({
          orientation: orientation
        });
      }
    }
  };
});

app.directive('mySplitterSplit', function(){
  return {
    require: '^mySplitter',
    restrict: 'A',
    link: function(scope, element, attrs, splitterCtrl) {
        splitterCtrl.split(); 
      }
  };
});

Working Example