web-dev-qa-db-ja.com

angular-ng-if-ng-ifテンプレートがレンダリングされた後にコールバックする方法

angularでは、特定のクラスの要素が読み込まれた後に関数を呼び出す必要があります。要素の表示は、ng-if = 'expr'によって制御されます。 $ scope.exprの値は、いくつかのajax呼び出しが応答した後に設定されます。

ここで、$ watchをexprに配置するか、$ evalAsyncを使用してみます。機能していません。これらのイベントは、テンプレートパーツが実際に実行される前に実行されるためと考えられます。

これがサンプルコードです: http://jsbin.com/kuyas/1/edit ここで、テンプレートがレンダリングされた後に実行されるng-ifに関するコールバックのようなものが必要です。

16
Charanjeet Kaur

問題は、angularがダイジェストループで実行され、すべての要素がレンダリングされていることを確認する)かどうかを知る方法がないことでした。

この問題を解決するには、2つのオプションがありました

  1. コールバック関数をディレクティブでラップします。 ng-ifにそのディレクティブを含めます。そして、あなたがあなたのコールバックが実行されることを望むときだけその表現を真にします。
  2. 内部でコールバック関数を呼び出します。setTimeOut(function(){ ... }, 0);は、ブラウザーがデフォルトですべてのイベントをキューに保持するため、ダイジェストループが実行されると、コールバック関数がキューに入り、ダイジェストループが終了するとすぐに実行されます。
19
Charanjeet Kaur

考えられる答えの1つは、やりたいことをすべて行うディレクティブを作成することです。次に、ng-ifによって制御されるHTMLのセクション内でのみそのディレクティブを使用すると、ng-if式がtrueになるまで、ディレクティブは休止します。

それでいいですか?

26
John Munsch

私の見解では、最も簡単な解決策は次のことです。

<div ng-if="sectionActivated">
    <div ng-init="callBack()"></div>
</div>

コールバックは、ng-ifの影響を受けるものがレンダリングされたときにのみ呼び出されます。

4
aBertrand

ディレクティブは次のようになります。

import * as angular from 'angular';

class OnFinishRenderDirective implements angular.IDirective {

  public restrict = 'A';
  public replace = false;

  public link = (
    scope: any,
    // scope:        angular.IScope,
    element: angular.IAugmentedJQuery,
    attr: any,
    modelCtrl: any,
    link: angular.ITemplateLinkingFunction ) => {

    if ( scope.$last === true ) {
      this.$timeout(() => {
        scope.$emit( 'elementRendered' );
      } );
    }

  }

  constructor( private $timeout: angular.ITimeoutService ) { }

}

export function onFinishRenderFactory(): angular.IDirectiveFactory {

  var directive = ( $timeout: angular.ITimeoutService ) => new OnFinishRenderDirective( $timeout );
  directive.$inject = [ '$timeout' ];
  return directive;
}

それをインポートしてモジュールに追加する必要があります

import { onFinishRenderFactory } from './onFinishRender/onFinishRender.directive';

angular.module( 'yourModule', [] )
.directive( 'onFinishRender', onFinishRenderFactory() )

次に、マークアップのどこかにディレクティブを使用して、ディレクティブがレンダリングされたときにイベントを発行できます。

<div onFinishRender>I am rendered</div>

ディレクティブDIVに追加の属性を追加して、リンク関数のATTRオブジェクトから取得し、$ emit関数に追加して、レンダリングするこの特定のDIVを識別することもできます。

それはあなたの質問に答えますか?

1
Mattijs