Использование JQuery с Angular.

Jquery начало.

Установим библиотекку.

npm install jquery @types/jquery --save
  • добавим в webpack

    “scripts”: [ “../node_modules/jquery/dist/jquery.min.js” ],

Добавим модуль box.ts.

import * as $ from "jquery";

export class Box {
    container: any;

    constructor(id: string){
        this.container = $(id);
        console.log(this.container);
    }
}

Включим модуль в приложение.

import { Box } from './box'
var box = new Box('#w-box');

Пришлось перегрузить vs code чтоб увидел типы

Получили ошибку компиляции.

error TS2304: Cannot find name 'Iterable'.

Необходимо включить библиотеки типов в tsconfig.json. Это переопределит дефолтные из target (es5).

"lib": [
  "es2016",
  "dom"
]

Усложним модуль Box.

import * as $ from "jquery";
import { Word } from './word';


export class Box { 
    container: any;

    constructor(id: string){
        this.container = $(id);
    }

    fill(lst: Array<Word>){

        lst.forEach(element => {
            this.container.append('<li>'+element.name+'</li>');
        });

    }

}

Приложение.

import { Word } from './word'
import { Box } from './box'

var box = new Box('#w-box');
var w1 = new Word('test','34');
var w2 = new Word('test2','342');

box.fill([w1,w2]);

Шаблон.

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <h1> Test </h1>
        <ul id="w-box"></ul>
        <script src="dist/wabpack.bundle.js"></script>
    </body>
</html>

Использование InjectionToken (OpaqueToken).

Создаем сервис.

jQuery.service.ts


import { InjectionToken } from '@angular/core';
export const JQ_TOKEN = new InjectionToken('jQuery'); // строка может быть любой

Добавляем провайдер.

import { JQ_TOKEN } from './jquery.service';
declare let jQuery: Object;


@NgModule({
  ...
  providers: [
    ...
    {provide: JQ_TOKEN, useValue: jQuery }
  ],
  ...

Используем Инжектором.

import { ... Inject } from '@angular/core';
import { JQ_TOKEN } from '../jquery.service';

...

constructor(@Inject(JQ_TOKEN) private $: any){}


ngOnInit() {  
   console.log(this.$(this));
}

Однако при таком подходе появляется ошибка компиляции.

ERROR in Error encountered resolving symbol values statically. Reference to a local (non-exported) symbol 'jQuery'. Consider exporting the symbol (position 10:13 in the original .ts file), resolving symbol AppModule in /home/zdimon/storage1/www/js/public-course/card/src/app/app.module.ts

Поэтому лучше использовать useFactory вместо useValue.

import { InjectionToken } from '@angular/core';
declare let jQuery: Object;
export const JQ_TOKEN = new InjectionToken('jQuery');
export function jQueryFactory() {
    return jQuery;
}

export const JQUERY_PROVIDER = [
    { provide: JQ_TOKEN, useFactory: jQueryFactory },
];
  • или можно напрямую использовать глобальный обьект window

    export function jQueryFactory() { return window[‘jQuery’]; }

В модуле.

import { JQUERY_PROVIDER } from './jquery.service';

  providers: [
    CardService,
    JQUERY_PROVIDER
  ],