web-dev-qa-db-ja.com

各コンポーネントの読み込みが完了した後、Angular 2でjquery関数を実行する方法

私はすべてのライフサイクルフックを試しましたが、必要な結果を達成することができません。私が必要とする結果は、これらの要素(コンポーネント)が1つ1つ読み込まれた後に、1つのページ上のさまざまな要素に使用される多くのjqueryプラグインを初期化する関数をトリガーすることです。

したがって、この構造を持っているとしましょう。

ホームページスライダーウィジェット製品の回転子..etc

これらの要素にはそれぞれ独自のコンポーネントがあり、すべてホームページの親コンポーネントの子です。

ここで必要なのは、すべての子コンポーネントと親コンポーネントがいつロードされるかを知ることです。そのため、1つのjquery関数をトリガーして、ページ上のすべてのプラグインを初期化します。

22
Joseph Girgis

AfterViewInit( https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview )をインポートすることにより、「ngAfterViewInit」ライフサイクルフックを使用します。次のように使用できます。

インストール:

    tsd install jquery --save

または

    typings install dt~jquery --global --save

利用:

    import { Component, AfterViewInit } from '@angular/core';
    import * as $ from 'jquery';

    ngAfterViewInit() {
        this.doJqueryLoad();     
        this.doClassicLoad();

        $(this.el.nativeElement)
            .chosen()
            .on('change', (e, args) => {
                this.selectedValue = args.selected;
            });
    }

    doClassicLoad() {
      // A $( document ).ready() block.
      $( document ).ready(function() {
          console.log( "Unnecessary..." );
      });      
    }

    // You don't need to use document.ready... 
    doJqueryLoad() {
        console.log("Can use jquery without doing document.ready")
        var testDivCount = $('#testDiv').length;
        console.log("TestDivCount: ", testDivCount);
    }

次に例を示します: http://plnkr.co/edit/KweZYO9hk9Dz8pqDK77F?p=info

24
Dan Weber

私が見つけた最も効果的な方法は、ページ/コンポーネントコンストラクター内で時間0のsetTimeoutを使用することです。 Angularがすべての子コンポーネントのロードを完了した後、次の実行サイクルでjQueryを実行しましょう。

export class HomePage {
    constructor() {
        setTimeout(() => {
            // run jQuery stuff here
        }, 0);
    }
}

NgOnInitメソッド内にsetTimeoutを配置することもうまくいきました。

export class HomePage {
    ngOnInit() {
        setTimeout(() => {
            // run jQuery stuff here
        }, 0);
    }
}
16
Urgo

どう?

_bootstrap(...).then(x => {
  ...
})
_

それ以外の場合、ルートコンポーネントのngAfterViewInit()は、要件に一致するライフサイクルフックであると想定しますが、すでにすべてをテストしたと述べています...

更新

ルートコンポーネントのbootstrap()またはngAfterViewInit()は、初期ロードにのみ使用できます。後で追加されたコンポーネントの場合、追加されたコンポーネントのngAfterViewInit()を使用できます。

4

ここでも同じ問題がありました。私は2つの解決策を見つけましたが、それらは最良ではありません:

1-jQueryプラグインが開始されているかどうかを確認するafterViewCheckedを実装し、変数を使用してその初期化を制御します。 afterViewCheckedが何度も呼び出されるため、これは難しい方法です。

2-ngIfの代わりにhiddenプロパティを使用して、いくつかの要素を非表示に変更しました。 hiddenを使用すると、afterViewInitを使用してすべてのjqueryプラグインを初期化し、オブジェクトが非表示であっても機能させることができます。

ngIfの使用時にsetTimeoutが機能しませんでした。コンテンツが再レンダリングされる前にトリガーされます。

1

可能な解決策の1つは、zone.onStableまたはzone.onMicrotaskEmpty

ngAfterViewInit() {
  this.zone.onStable.first().subscribe(() => {
    debugger;
  });
}

または

ngOnInit() {
  this.service.getData().subscribe(() => {
    this.data = data;
    this.zone.onMicrotaskEmpty.first().subscribe((data) => {
      $(someElem).plugin();
    });
  });
}

こちらもご覧ください

1
yurzui