How to run a jquery function in Angular 2 after every component finish loading

前端 未结 5 1003
感动是毒
感动是毒 2020-11-30 07:02

I have tried all the life cycle hooks but can\'t get to accomplish the needed result. The result that I need is triggering a function that initialize many jquery plugins us

相关标签:
5条回答
  • 2020-11-30 07:13

    You will want to use the "ngAfterViewInit" lifecycle hook, through importing AfterViewInit (https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview). You can use it as shown below:

    Installation:

        tsd install jquery --save
    

    or

        typings install dt~jquery --global --save
    

    Utilization:

        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);
        }
    

    Here is a plunker for an example: http://plnkr.co/edit/KweZYO9hk9Dz8pqDK77F?p=info

    0 讨论(0)
  • 2020-11-30 07:13

    what about

    bootstrap(...).then(x => {
      ...
    })
    

    otherwise I would assume ngAfterViewInit() of your root component to be a lifecycle hook that matches your requirement but you stated that you tested all already ...

    update

    bootstrap() or ngAfterViewInit() on the root component can only be used for the initial load. For later added components the ngAfterViewInit() of the added components can be used.

    0 讨论(0)
  • 2020-11-30 07:14

    One possible solution would be subscribing on zone.onStable or zone.onMicrotaskEmpty

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

    or

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

    See also

    • Angular 2 calling jQuery after rendering elements - after consuming API
    0 讨论(0)
  • 2020-11-30 07:17

    I had the same problem here. I found 2 solutions, even they are not the best:

    1 - Implement afterViewChecked to check if jquery plugin is initiated and then use a variable to control its initialization. This is the hard way because afterViewChecked is called many times.

    2 - I changed some elements to be hidden using hidden property instead of ngIf. With hidden I could initialize all the jquery plugins using afterViewInit and make they work even my objects are hidden.

    setTimeout did not work when using ngIf. It triggers before the content is re-rendered.

    0 讨论(0)
  • 2020-11-30 07:21

    The most effective way that I have found is to use setTimeout with time of 0 inside of the page/component constructor. This let's the jQuery run in the next execution cycle after Angular has finished loading all the child components.

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

    Putting the setTimeout inside of ngOnInit method has also worked for me.

    export class HomePage {
        ngOnInit() {
            setTimeout(() => {
                // run jQuery stuff here
            }, 0);
        }
    }
    
    0 讨论(0)
提交回复
热议问题