AngularJS ngRepeat - 监听元素移动(我需要使用ngRepeat渲染iframe列表)

时间:2014-02-19 08:12:14

标签: javascript angularjs iframe tinymce angularjs-ng-repeat

我使用 ng-repeat 指令呈现TinyMCE wysiwygs列表:

<div ng-repeat="widget in wigdets">
   <textarea wysiwyg></textarea> <!-- This is a directive to initialize TinyMCE -->
</div>

当我更改控制器中小部件的顺序时,TinyMCE的实例会相应地自动重新排列。

问题是TinyMCE小部件是一个iframe,iframe状态在DOM中移动时会被重置。

所以我需要保存TinyMCE内容并在移动之前从元素中删除TinyMCE,然后再次初始化TinyMCE并在移动完成后应用保存的内容。

是否有一种简单的方法以某种方式挂钩ng-repeat并注册元素移动的回调?

如果我必须编写自己的 ng-repeat-custom 指令,那么以角度方式组织事件调度的正确架构是什么?

我应该以某种方式向子指令发送事件吗?或者子指令(在我的情况下是 wysiwyg )是否订阅了父指令的事件?

2 个答案:

答案 0 :(得分:1)

应讨论对父母的子指令,并最终包括使用两个实体的完整指令圈。

答案 1 :(得分:1)

问题实际上归结为“当ng-repeat完成DOM操作时我如何做某事”。 我在类似的问题中找到了答案:Calling a function when ng-repeat has finished

在我的情况下,它很简单,因为控制器负责修改小部件列表。因此,我只需发出$scope.emit('pre_move')$scope.emit('after_move')事件,然后在我的wysiwyg指令中处理它们。

重要的是在 $ timeout()中包装'after_move'!它保证执行将在下一个摘要周期开始,你可以确定所有DOM操作都在那时完成。

控制器:

function controller($scope, $timeout) {
    var widget1 = new Widget();
    var widget2 = new Widget();

    $scope.widgets = [widget1, widget2]

    $scope.emit('pre_move'); 

   // Shuffle widgets
   $scope.widgets[0] = widget2;
   $scope.widgets[1] = widget1;

   $timeout(function(){
        // $timeout wrapper is required to ensure that event will be emited 
        // in the next digest cycle
        $scope.emit('post_move');
   })

}

Wysiwyg TinyMCE指令:

link: function(scope, element, attrs) {
      ...

      var content;
      scope.on('pre_move', function() {
         content = element.html();
         element.tinymce().remove; // remove TinyMCE before movement
      });

      var content;
      scope.on('post_move', function() {
         element.tinymce().html(content); // reinitialize TinyMCE after movement
      });
}