本文翻译自:How to use jQuery with Angular?
Can anyone tell me, how to use jQuery with Angular ? 谁能告诉我,如何在Angular中使用jQuery ?
class MyComponent {
constructor() {
// how to query the DOM element from here?
}
}
I'm aware there are workarounds like manipulating the class or id of the DOM element upfront, but I'm hoping for a cleaner way of doing it. 我知道有一些变通方法,例如预先处理DOM元素的类或ID ,但我希望有一种更干净的方法。
参考:https://stackoom.com/question/24Uef/如何在Angular中使用jQuery
Using jQuery from Angular2 is a breeze compared to ng1. 与ng1相比,使用来自Angular2的jQuery轻而易举。 If you are using TypeScript you could first reference jQuery typescript definition. 如果您使用的是TypeScript,则可以先引用jQuery打字稿定义。
tsd install jquery --save
or
typings install dt~jquery --global --save
TypescriptDefinitions are not required since you could just use any
as the type for $
or jQuery
不需要TypescriptDefinitions,因为您可以将$
或jQuery
用作any
类型
In your angular component you should reference a DOM element from the template using @ViewChild()
After the view has been initialized you can use the nativeElement
property of this object and pass to jQuery. 在您的角度组件中,您应该使用@ViewChild()
引用模板中的DOM元素。初始化视图之后,您可以使用此对象的nativeElement
属性并传递给jQuery。
Declaring $
(or jQuery
) as JQueryStatic will give you a typed reference to jQuery. 将$
(或jQuery
)声明为JQueryStatic将为您提供对jQuery的类型化引用。
import {bootstrap} from '@angular/platform-browser-dynamic';
import {Component, ViewChild, ElementRef, AfterViewInit} from '@angular/core';
declare var $:JQueryStatic;
@Component({
selector: 'ng-chosen',
template: `<select #selectElem>
<option *ngFor="#item of items" [value]="item" [selected]="item === selectedValue">{{item}} option</option>
</select>
<h4> {{selectedValue}}</h4>`
})
export class NgChosenComponent implements AfterViewInit {
@ViewChild('selectElem') el:ElementRef;
items = ['First', 'Second', 'Third'];
selectedValue = 'Second';
ngAfterViewInit() {
$(this.el.nativeElement)
.chosen()
.on('change', (e, args) => {
this.selectedValue = args.selected;
});
}
}
bootstrap(NgChosenComponent);
This example is available on plunker: http://plnkr.co/edit/Nq9LnK?p=preview 该示例可在plunker上找到: http ://plnkr.co/edit/Nq9LnK?p=preview
tslint will complain about chosen
not being a property on $, to fix this you can add a definition to the JQuery interface in your custom *.d.ts file tslint会抱怨chosen
不是$的属性,要解决此问题,您可以在自定义* .d.ts文件的JQuery接口中添加定义
interface JQuery {
chosen(options?:any):JQuery;
}
You can implement the lifecycle hook ngAfterViewInit() to add some DOM manipulations 您可以实现生命周期挂钩ngAfterViewInit()来添加一些DOM操作
ngAfterViewInit() {
var el:any = elelemtRef.domElement.children[0];
$(el).chosen().on('change', (e, args) => {
_this.selectedValue = args.selected;
});
}
Be careful when using router because angular2 may recycle views .. so you have to be sure that the DOM elements manipulations are done only in the first call of afterViewInit .. ( You can use static boolean variables to do so ) 使用router时要小心,因为angular2可能会回收视图..因此,必须确保仅在afterViewInit的第一次调用中才对DOM元素进行操作。(可以使用静态布尔变量来执行此操作)
class Component {
let static chosenInitialized : boolean = false;
ngAfterViewInit() {
if (!Component.chosenInitialized) {
var el:any = elelemtRef.domElement.children[0];
$(el).chosen().on('change', (e, args) => {
_this.selectedValue = args.selected;
});
Component.chosenInitialized = true;
}
}
}
The most effective way that I have found is to use setTimeout with time of 0 inside of the page/component constructor. 我发现的最有效的方法是在页面/组件构造函数内部使用setTimeout并将时间设置为0。 This let's the jQuery run in the next execution cycle after Angular has finished loading all the child components. 这使jQuery在Angular完成加载所有子组件之后的下一个执行周期中运行。 A few other component methods could be used but all I have tried work best when run inside a setTimeout. 可以使用其他一些组件方法,但是在setTimeout中运行时,我尝试过的所有方法均能达到最佳效果。
export class HomePage {
constructor() {
setTimeout(() => {
// run jQuery stuff here
}, 0);
}
}
1) To access DOM in component. 1)访问组件中的DOM。
import {BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
constructor(el: ElementRef,public zone:NgZone) {
this.el = el.nativeElement;
this.dom = new BrowserDomAdapter();
}
ngOnInit() {
this.dom.setValue(this.el,"Adding some content from ngOnInit");
}
You can include jQuery in following way. 您可以通过以下方式包含jQuery。 2) Include you jquery file in index.html before angular2 loads 2)在angular2加载之前,将jquery文件包含在index.html中
<head>
<title>Angular 2 QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- jquery file -->
<script src="js/jquery-2.0.3.min.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
You can use Jquery in following way, Here i am using JQuery Ui date picker. 您可以通过以下方式使用Jquery,在这里,我正在使用JQuery Ui日期选择器。
import { Directive, ElementRef} from '@angular/core';
declare var $:any;
@Directive({
selector: '[uiDatePicker]',
})
export class UiDatePickerDirective {
private el: HTMLElement;
constructor(el: ElementRef) {
this.el = el.nativeElement;
}
ngOnInit() {
$(this.el).datepicker({
onSelect: function(dateText:string) {
//do something on select
}
});
}
}
This work for me. 这项工作对我来说。
I do it in simpler way - first install jquery by npm in console: npm install jquery -S
and then in component file I just write: let $ = require('.../jquery.min.js')
and it works! 我用更简单的方式做到这一点-首先在控制台上通过npm安装jquery: npm install jquery -S
,然后在组件文件中我只写: let $ = require('.../jquery.min.js')
! Here full example from some my code: 这里是一些我的代码的完整示例:
import { Component, Input, ElementRef, OnInit } from '@angular/core';
let $ = require('../../../../../node_modules/jquery/dist/jquery.min.js');
@Component({
selector: 'departments-connections-graph',
templateUrl: './departmentsConnectionsGraph.template.html',
})
export class DepartmentsConnectionsGraph implements OnInit {
rootNode : any;
container: any;
constructor(rootNode: ElementRef) {
this.rootNode = rootNode;
}
ngOnInit() {
this.container = $(this.rootNode.nativeElement).find('.departments-connections-graph')[0];
console.log({ container : this.container});
...
}
}
In teplate I have for instance: 在teplate中,例如:
<div class="departments-connections-graph">something...</div>
EDIT 编辑
Alternatively instead of using: 或者,代替使用:
let $ = require('../../../../../node_modules/jquery/dist/jquery.min.js');
use 采用
declare var $: any;
and in your index.html put: 并在您的index.html中放:
<script src="assets/js/jquery-2.1.1.js"></script>
This will initialize jquery only once globaly - this is important for instance for use modal windows in bootstrap... 这只会初始化一次全局查询-这对于例如在引导程序中使用模式窗口很重要...