在每个组件完成加载后如何在 Angular 2 中运行 jquery 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35728731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:03:46  来源:igfitidea点击:

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

jquerycomponentsangularonloaddocument-ready

提问by Joseph Girgis

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 used for different elements on a single page after every single one of these elements (components) is loaded.

我已经尝试了所有生命周期钩子,但无法完成所需的结果。我需要的结果是触发一个函数,该函数在加载这些元素(组件)中的每一个之后初始化用于单个页面上不同元素的许多 jquery 插件。

So lets say that you have this structure.

所以让我们说你有这个结构。

Home Page Slider Widgets Product rotators ..etc

主页滑块小部件产品旋转器..等

Every one of these elements has it's own component and all are children of the Home page parent component.

这些元素中的每一个都有自己的组件,并且都是主页父组件的子级。

And what I need here is to know when all the children components and the parent component is loaded so I trigger one jquery function to initialize every plugin on the page.

我在这里需要的是知道何时加载所有子组件和父组件,以便我触发一个 jquery 函数来初始化页面上的每个插件。

回答by Dan Weber

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:

您将需要通过导入 AfterViewInit ( https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#afterview)来使用“ngAfterViewInit”生命周期钩子。您可以使用它,如下所示:

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

这是一个 plunker 示例:http://plnkr.co/edit/KweZYO9hk9Dz8pqDK77F?p=info

回答by Urgo

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.

我发现的最有效的方法是在页面/组件构造函数中使用时间为 0 的 setTimeout。这让 jQuery 在 Angular 完成加载所有子组件后的下一个执行周期中运行。

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

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

将 setTimeout 放在 ngOnInit 方法中也对我有用。

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

回答by Günter Z?chbauer

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 ...

否则我会假设ngAfterViewInit()你的根组件是一个符合你要求的生命周期钩子,但你说你已经测试了所有......

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.

bootstrap()或者ngAfterViewInit()在根组件上只能用于初始加载。对于以后添加的组件,ngAfterViewInit()可以使用添加的组件。

回答by Cristal Embalagens

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

我在这里遇到了同样的问题。我找到了 2 个解决方案,即使它们不是最好的:

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.

1 - 实现 afterViewChecked 以检查 jquery 插件是否已启动,然后使用变量来控制其初始化。这是很难的方法,因为 afterViewChecked 被多次调用。

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.

2 - 我使用隐藏属性而不是 ngIf 更改了一些要隐藏的元素。使用 hidden 我可以使用 afterViewInit 初始化所有 jquery 插件,并使它们即使我的对象被隐藏也能工作。

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

使用 ngIf 时 setTimeout 不起作用。它在重新渲染内容之前触发。

回答by yurzui

One possible solution would be subscribing on zone.onStableor zone.onMicrotaskEmpty

一种可能的解决方案是订阅zone.onStablezone.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

也可以看看