Odpowiednik $ document.ready () w Angular2

86

Mam nadzieję, że proste pytanie.

Chcę uruchomić skrypt, gdy zostanie uruchomiony odpowiednik $ document.ready () w Angular2. Jaki jest najlepszy sposób, aby to osiągnąć?

Próbowałem umieścić skrypt na końcu index.html, ale jak się dowiedziałem, to nie działa! Rozumiem, że musi iść w jakiejś deklaracji komponentu?

Czy można uruchomić ładowanie skryptu z .jspliku?

EDYCJA - Kod:

Mam następujące wtyczki js i css wstrzyknięte do mojej aplikacji (z motywu html Foundry ).

    <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

Jak już wspomniano, skrypt scripts.js `` tworzy instancję '' całej rzeczy i dlatego należy go uruchomić, gdy Angular będzie gotowy. script.js

Działa:

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
    }
Chris
źródło
po kilku godzinach poszukiwań nadal mam ten sam problem. > Nie znaleziono modułu: Błąd: nie można rozwiązać '@ types / jquery' Zainstalowałem go za pomocą npm install --save -D @ types / jquery, a potem próbuję zaimportować go do modułu (ze względu na to, że otrzymałem wiadomość z przybornika, że ​​nie zna $ z jQuery) w moim Component.ts, mówi moja pierwsza wiadomość! Mam nadzieję, że moje wyjaśnienia są prawidłowe. Jeszcze raz dziękuję za całą pomoc, jakiej udzieliła mi ta społeczność! btw: To moja pierwsza prawdziwa wiadomość, więc mam nadzieję, że napiszę dobrą
Alexandre Saison

Odpowiedzi:

37

Możesz samodzielnie uruchomić zdarzenie w ngOnInit()komponencie głównym Angular, a następnie nasłuchiwać tego zdarzenia poza Angular.

To jest kod Darta (nie znam TypeScript), ale nie powinien być trudny do przetłumaczenia

@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'));
  }
}
Günter Zöchbauer
źródło
Ok idealnie. Czy mógłbyś podać szybki przykład takiego kodu? Przepraszamy, ale całkiem nowy w ng2
Chris,
Najlepiej, gdybym mógł załadować plik js, gdy wystąpi onInit. Ten plik zawiera cały mój kod gotowy do dokumentu (z szablonu HTML, którego używam) i jest w js, więc nie mogę go po prostu skopiować, ponieważ piszę ng2 w .ts
Chris,
Sprawdź odniesienie do ngOnInit.
Boris
1
@Borys to nie prowadzi mnie zbyt daleko Obawiam się
Chris
9
Następnie po prostu uruchom kod w ngAfterViewInit() { ... }. Nie ma potrzeby odpalania wydarzenia.
Günter Zöchbauer
64

Kopiowanie odpowiedzi od Chrisa:

Działa:

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
    }
Sameer Alibhai
źródło
4
Nie wiem, dlaczego głosy przeciw. To zadziałało dla mnie, ale wprowadziło również wyścig między starszym kodem JS, który próbowałem uruchomić, a kompilatorem widoku. Skończyło się AfterViewCheckedna tym, że użyłem, ale mimo wszystko oto upvote za skierowanie mnie we właściwym kierunku.
lukiffer
1
To może zadziałać, ale może nie być najlepszą praktyką. Lepiej by było, gdyby cały kod zewnętrzny był opakowany w jakąś globalną funkcję, ale z dobrze rozmieszczonymi nazwami, a następnie wywołała tę funkcję z ngAfterViewInit(). Np window.MY_APP = {}; MY_APP.init = function () {/*copy all that script.js here*/ }. Następnie w komponencie, import ...; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } }ale najważniejsze jest to, że nie masz aplikacji angular2 - twój script.js jest w zasadzie starą stroną jquery. Większość z nich można by zamienić na komponenty NG2.
Zlatko
1
Nie obniżam tego, ale w tej metodzie mogę dotrzeć do elementów DOM. Jednak gdy próbuję pobrać element.css ('wysokość'), zwraca do mnie 0px. Dlatego nie mogę go użyć do ustawienia css.
Blast
U mnie zadziałało idealnie :) Myślę, że na tym etapie masz już DOM, ale może nie masz jeszcze załadowanych wszystkich źródeł, takich jak obrazy. Więc jest dokładnie tak $document.ready().
Affilnost
1
Słodko i gładko!
Sam
17

Wybrałem to rozwiązanie, więc nie musiałem włączać mojego niestandardowego kodu js do komponentu innego niż funkcja jQuery $ .getScript .

Uwaga: ma zależność od jQuery. Będziesz więc potrzebował typów jQuery i jQuery.

Zauważyłem, że jest to dobry sposób na obejście niestandardowych lub dostawców plików js, które nie mają dostępnych typów, dzięki czemu TypeScript nie krzyczy na ciebie, gdy idziesz, aby uruchomić aplikację.

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

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

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

Aktualizacja Właściwie w moim scenariuszu zdarzenie cyklu życia OnInit działało lepiej, ponieważ uniemożliwiło załadowanie skryptu po załadowaniu widoków, co miało miejsce w przypadku ngAfterViewInit, i spowodowało, że widok pokazywał nieprawidłowe pozycje elementu przed załadowaniem skryptu.

ngOnInit() {
    $.getScript('../js/mimity.js');
  }
dynamiclynk
źródło
Otrzymuję, Cannot find name '$'.gdy próbuję naśladować ten przykład?
kod jedzenia i snu
3
@ eat-sleep-code Myślę, że potrzebujesz typów jQuery, a co powiesz na spróbowanie npm install @types/jquery -D? : D
realappie
4

Aby użyć jQuery wewnątrz Angulara, zadeklaruj tylko $ w następujący sposób: deklaruj var $: any;

Ilir Hushi
źródło
gdzie to położyłeś?
Dan Chase
@DanChase możesz umieścić go po imporcie bibliotek w klasie
Ilir Hushi
spójrz na ten fajny artykuł dotyczący wyłączania jquery przy użyciu angular-cli: medium.com/@swarnakishore/…
Pavel
3

przyjęta odpowiedź nie jest poprawna i biorąc pod uwagę pytanie, nie ma sensu jej akceptować

ngAfterViewInit uruchomi się, gdy DOM będzie gotowy

whine ngOnInit uruchomi się, gdy komponent strony dopiero zaczyna być tworzony

phil123456
źródło
1
Staraj się bardzo jasno opisać swoje rozwiązanie w swojej odpowiedzi, a jeśli uważasz, że jakaś odpowiedź jest nieprawidłowa, rozważ skomentowanie tego pytania.
Zeeshan Adil,
nie ma problemu, po prostu spróbuj wyjaśnić swoją odpowiedź, aby pomóc większej liczbie osób. z minimalistycznym przykładem kodu.
Zeeshan Adil
0

W pliku main.ts bootstrap po DOMContentLoaded, więc angular zostanie załadowany, gdy DOM jest w pełni załadowany.

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));
});
Vikas Kandari
źródło