1. ホーム
  2. angularjs

[解決済み] Angular JSディレクティブのポストレンダリングコールバックはありますか?

2022-06-03 17:22:34

質問

私は、このように要素に追加するためにテンプレートを取り込むディレクティブを手に入れました。

# CoffeeScript
.directive 'dashboardTable', ->
  controller: lineItemIndexCtrl
  templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
  (scope, element, attrs) ->
    element.parent('table#line_items').dataTable()
    console.log 'Just to make sure this is run'

# HTML
<table id="line_items">
    <tbody dashboard-table>
    </tbody>
</table>

また、DataTablesというjQueryプラグインを使用しています。一般的な使い方は、$('table#some_id').dataTable()のような感じです。dataTable()の呼び出しにJSONデータを渡してテーブルデータを提供することもできますし、ページ上にすでにデータがあれば残りを処理してくれることもできます...。私は後者で、HTMLページ上にすでに行がある状態にしています。

しかし、問題は、DOM readyの後にtable#line_itemsのdataTable()を呼び出さなければならないことです。私の上記のディレクティブは、テンプレートがディレクティブの要素に追加される前に、dataTable()メソッドを呼び出します。追加された後に関数を呼び出すことができる方法はありますか?

助けてくれてありがとうございます。

Andyの回答後のUPDATE1です。

私はlinkメソッドがページ上のすべてが終わった後にのみ呼び出されることを確認したいので、私は小さなテストのためにディレクティブを変更しました。

# CoffeeScript
#angular.module(...)
.directive 'dashboardTable', ->
    {
      link: (scope,element,attrs) -> 
        console.log 'Just to make sure this gets run'
        element.find('#sayboo').html('boo')

      controller: lineItemIndexCtrl
      template: "<div id='sayboo'></div>"

    }

そして、div#saybooに"boo"が確かに表示されています。

次に、私のjquery datatableの呼び出しを試してみます。

.directive 'dashboardTable',  ->
    {
      link: (scope,element,attrs) -> 
        console.log 'Just to make sure this gets run'
        element.parent('table').dataTable() # NEW LINE

      controller: lineItemIndexCtrl
      templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
    }

運が悪い

次に、タイムアウトを追加してみます。

.directive 'dashboardTable', ($timeout) ->
    {
      link: (scope,element,attrs) -> 
        console.log 'Just to make sure this gets run'
        $timeout -> # NEW LINE
          element.parent('table').dataTable()
        ,5000
      controller: lineItemIndexCtrl
      templateUrl: "<%= asset_path('angular/templates/line_items/dashboard_rows.html') %>"
    }

で、うまくいきました。では、タイマーを使わないバージョンのコードでは何が間違っているのでしょうね?

どのように解決するのですか?

2番目のパラメータである "delay" が提供されていない場合、デフォルトの動作はDOMのレンダリングが完了した後に関数を実行することです。そのため、setTimeoutの代わりに、$timeoutを使用します。

$timeout(function () {
    //DOM has finished rendering
});