2014-02-19 2 views
1

Я рендеринг списка TinyMCE wysiwygs с использованием нг-повторить директивы:AngularJS ngRepeat - слушать движение элемента (мне нужно сделать список фреймов с ngRepeat)

<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 в моем случае) подписываться на события родительских директив?

ответ

1

Директивы ребенка для родителя должны обсуждаться и в конечном итоге включать полный круг директив для использования обоих объектов.

+1

Может быть, вы могли бы разработать более. – cpburnz

1

Проблема на самом деле сводится к «как я что-то делаю, когда ng-repeat заканчивает манипуляции с DOM». И я нашел ответ в аналогичном вопросе: Calling a function when ng-repeat has finished

В моем случае это просто, потому что диспетчер отвечает за изменение списка виджетов. Поэтому я могу просто испустить $scope.emit('pre_move') и $scope.emit('after_move') событие и обработать их в моей директиве wysiwyg.

Важно, чтобы обернуть «after_move» в $ timeout()! Он гарантирует, что выполнение начнется в следующем цикле дайджеста, и вы можете быть уверены, что все манипуляции с 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 
     }); 
} 
Смежные вопросы