相当于$ document.ready()的Angular2


86

我希望这是一个简单的问题。

我要在等效于$ document.ready()的Angular2上运行脚本。实现此目标的最佳方法是什么?

我尝试将脚本放在的末尾index.html,但是据我发现,这不起作用!我认为它必须包含某种组件声明?

是否可以从.js文件运行加载脚本?

编辑-代码:

我已经将以下js和css插件注入到我的应用程序中(来自Foundry html主题)。

    <link href="css/themify-icons.css" rel="stylesheet" type="text/css" media="all" />
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css" media="all" />
    ...


    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/flexslider.min.js"></script>
    ...
    <script src="js/scripts.js"></script> //This initiates all the plugins

如前所述,scripts.js会“实例化”整个过程,因此需要在Angular准备好后运行。script.js

得到它的工作:

import {Component, AfterViewInit} from 'angular2/core';

@Component({
  selector: 'home',
  templateUrl: './components/home/home.html'
})
export class HomeCmp implements AfterViewInit {


    ngAfterViewInit() {
       //Copy in all the js code from the script.js. Typescript will complain but it works just fine
    }

经过几个小时的研究,我仍然遇到同样的问题。>找不到模块:错误:无法解析'@ types / jquery'我使用npm install --save -D @ types / jquery安装了它,然后当我尝试将其导入模块中时(由于我在我的Component.ts中从工具箱中收到一条消息,提示它不知道来自jQuery的$),它说了我的第一条消息!我希望我的解释是正确的,再次感谢这个社区对我的所有帮助!顺便说一句:这是我的第一个真实信息,所以我希望写一封好信息
Alexandre Saison

Answers:


37

您可以自己在ngOnInit()Angular根组件中触发事件,然后在Angular之外侦听此事件。

这是Dart代码(我不知道TypeScript),但翻译起来不难

@Component(selector: 'app-element')
@View(
    templateUrl: 'app_element.html',
)
class AppElement implements OnInit {
  ElementRef elementRef;
  AppElement(this.elementRef);

  void ngOnInit() {
    DOM.dispatchEvent(elementRef.nativeElement, new CustomEvent('angular-ready'));
  }
}

好的,完美。您能否提供此类代码的快速示例?抱歉,但是对ng2来说还很陌生
克里斯(Chris)

最好是,我希望能够在onInit发生时加载js文件。该文件包含我所有准备好的文档代码(来自我正在使用的html模板),并且位于js中,所以我不能只复制粘贴它,因为我正在.ts中编写ng2
Chris

检查ngOnInit的参考
鲍里斯(Boris)2015年

1
@Boris恐怕我不会走得太远
Chris

9
然后,您只需在中运行代码ngAfterViewInit() { ... }。无需触发事件。
君特Zöchbauer

64

复制克里斯的答案:

得到它的工作:

import {AfterViewInit} from 'angular2/core';    

export class HomeCmp implements AfterViewInit {    

    ngAfterViewInit() {
       //Copy in all the js code from the script.js. Typescript will complain but it works just fine
    }

4
不确定为什么要投票。这对我有用,但也引入了我试图运行的旧版JS代码与视图编译器之间的竞争。我最终使用了AfterViewChecked,但都一样,这是朝正确方向指点我的赞誉。
lukiffer

1
这可能有效,但可能不是最佳实践。最好将所有外部代码包装在一些全局但名称空间合理的函数中,然后从中调用此函数ngAfterViewInit()。例如window.MY_APP = {}; MY_APP.init = function () {/*copy all that script.js here*/ }。然后在您的组件中,import ...; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } }但最重要的还是您没有angular2应用-您的script.js基本上是老式的jquery页面。您可以将其大部分转换为NG2组件。
Zlatko

1
我不是对此表示反对,但是通过这种方法,我可以访问DOM元素。但是,当我尝试获取element.css('height')时,它返回给我0px,因此我无法将其用于设置CSS。
Blast

它非常适合我:)我认为,在此阶段,您已经有DOM,但可能尚未加载所有源,例如图像。因此,它就像$document.ready()
Affilnost

1
甜美而光滑!
山姆

17

我采用了这种解决方案,因此除了jQuery $ .getScript函数之外,我不必在组件中包含我的自定义js代码。

注意:对jQuery有依赖性。因此,您将需要jQuery和jQuery类型。

我发现这是解决自定义或供应商js文件的好方法,这些文件没有可用的打字方式,而TypeScript在您启动应用程序时不会对您大喊大叫。

import { Component,AfterViewInit} from '@angular/core'

@Component({
  selector: 'ssContent',
  templateUrl: 'app/content/content.html',
})
export class ContentComponent implements AfterViewInit  {

  ngAfterViewInit(){
    $.getScript('../js/myjsfile.js');
  }
}

更新 实际上,在我的场景中,OnInit生命周期事件工作得更好,因为它阻止了视图加载后脚本的加载(这是ngAfterViewInit的情况),并且导致视图在脚本加载之前显示不正确的元素位置。

ngOnInit() {
    $.getScript('../js/mimity.js');
  }

Cannot find name '$'.当我尝试遵循此示例时,我会明白吗?
eat-sleep-code

3
@ eat-sleep-code我认为您需要jQuery输入,如何npm install @types/jquery -D出手呢?:D
realappie


3

接受的答案不正确,考虑到这个问题,接受它没有任何意义。

ngAfterViewInit将在DOM准备就绪时触发

当ngOnInit将在页面组件开始创建时触发


1
尝试仅对答案中的解决方案非常清楚,如果您认为某个答案不正确,请考虑对该问题进行评论。
Zeeshan Adil

没问题,请尝试使您的答案更清楚,以帮助更多的人。带有一个极简代码示例。
Zeeshan Adil

0

在DOMContentLoaded之后在main.ts文件中引导,以便在完全加载DOM时加载angular。

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}



document.addEventListener('DOMContentLoaded', () => {
  platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.