Почему мне нужно использовать тайм-аут?

Я использую AngularJS и библиотеку angular-datatable. Мне нужно вызвать модальное окно при нажатии на строку. Вот моя часть кода:

  function rowCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
    // Unbind first in order to avoid any duplicate handler (see https://github.com/l-lin/angular-datatables/issues/87)
    $('td', nRow).unbind('click');
    $('td', nRow).bind('click', function() {
      console.log(aData.title);
      $timeout(function(){
        Modal.showModal({
         template : 'views/Modal.html',
         Data : aData
         });
      }, 0);
    });
    return nRow;
  }

Функция console.log отлично работает в любом случае, но вызов модальной функции работает должным образом только тогда, когда он заключен в тайм-аут. Так может кто-нибудь объяснить, почему это происходит? Почему хорошо работает только первая функция? Буду признателен за любые пояснения.


person Dima Adas    schedule 14.10.2015    source источник
comment
да, это сервис, но он не работает, даже если я не буду вводить в него какие-либо параметры. И console.log работает с aData в любом случае). За ответ.   -  person Dima Adas    schedule 14.10.2015


Ответы (2)


Причина, по которой вам нужен $timeout, заключается в том, что вы используете событие jQuery с функцией angular. В целом это плохая идея, и она противоречит принципам проектирования angular — вместо этого используйте ng-click.

Если вы должны смешивать jQuery и angular вместе, убедитесь, что вы делаете это правильно, информируя angular о событиях jQuery, чтобы он мог запускать свой цикл дайджеста.

Вы можете запустить дайджест несколькими способами, но самый простой (и наиболее очевидный в отношении того, что делает ваш код) — это использовать $scope.$apply:

$scope.$apply(function () {

  Modal.showModal({
   template : 'views/Modal.html',
   Data : aData
  });

});

Причина, по которой $timeout работает, заключается в том, что $timeout — это функция-оболочка angular, которая запускает цикл дайджеста как часть своей реализации (на самом деле она очень похожа на $scope.$apply, но менее очевидно, что она делает / зачем она нужна, когда вы позже просматриваете свой код, поэтому Вместо этого я бы посоветовал использовать $scope.$apply).

Дополнительная литература: ng-book.

person Ed_    schedule 14.10.2015

Нет обратного вызова, когда механизм рендеринга браузера завершит рендеринг страницы.

Но рендеринг страницы обрабатывается очередью событий. Используя функцию $timeout, вы назначаете Modal.showModal концу очереди событий — после методов рендеринга страницы, которые уже поставлены в очередь.

Поэтому Modal.showModal будет вызываться после того, как страница будет отрисована и будет работать правильно.

person James Drummond    schedule 14.10.2015
comment
Не очень актуально, так как это событие срабатывает по клику. - person Ed_; 14.10.2015