Angular2-Äquivalent von $ document.ready ()

86

Einfache Frage, hoffe ich.

Ich möchte ein Skript ausführen, wenn das Angular2-Äquivalent von $ document.ready () ausgelöst wird. Was ist der beste Weg, um dies zu erreichen?

Ich habe versucht, das Skript am Ende von zu setzen index.html, aber wie ich herausgefunden habe, funktioniert das nicht! Ich nehme an, dass es in einer Art Komponentendeklaration gehen muss?

Ist es möglich, das Skript aus einer .jsDatei zu laden ?

EDIT - Code:

Ich habe die folgenden JS- und CSS-Plugins in meine Anwendung eingefügt (aus dem Foundry-HTML-Thema ).

    <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

Wie bereits erwähnt, "instanziiert" die Datei "scripts.js" das Ganze und muss daher ausgeführt werden, nachdem Angular bereit ist. script.js

Habe es geschafft:

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
quelle
Nach einigen Stunden Recherche bekam ich immer noch das gleiche Problem. > Modul nicht gefunden: Fehler: '@ types / jquery' kann nicht behoben werden. Ich habe es mit npm install installiert --save -D @ types / jquery. Wenn ich dann versuche, es in das Modul zu importieren (aufgrund der Tatsache, dass i Ich habe eine Nachricht aus der Toolbox erhalten, die $ von jQuery nicht kennt.) In meiner Component.ts steht meine erste Nachricht! Ich hoffe, meine Erklärungen sind richtig. Nochmals vielen Dank für die Hilfe, die diese Community mir gegeben hat! Übrigens: Dies ist meine erste echte Nachricht, also hoffe ich, eine gute zu schreiben
Alexandre Saison

Antworten:

37

Sie können ein Ereignis selbst in ngOnInit()Ihrer Angular-Stammkomponente auslösen und dann außerhalb von Angular auf dieses Ereignis warten.

Dies ist Dart-Code (ich kenne TypeScript nicht), sollte aber nicht zu schwer zu übersetzen sein

@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
quelle
OK perfekt. Könnten Sie möglicherweise ein kurzes Beispiel für einen solchen Code liefern? Sorry, aber ziemlich neu in ng2
Chris
Am liebsten möchte ich eine js-Datei laden können, wenn onInit auftritt. Diese Datei enthält meinen gesamten Dokument-Ready-Code (aus einer von mir verwendeten HTML-Vorlage) und befindet sich in js. Daher kann ich ihn nicht einfach kopieren und einfügen, da ich ng2 in .ts schreibe
Chris
Überprüfen Sie die Referenz für ngOnInit.
Boris
1
@ Boris es bringt mich leider nicht sehr weit
Chris
9
Dann führen Sie einfach den Code ein ngAfterViewInit() { ... }. Sie müssen kein Ereignis auslösen.
Günter Zöchbauer
64

Kopieren der Antwort von Chris:

Habe es geschafft:

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
quelle
4
Ich bin mir nicht sicher, warum die Abstimmungen. Dies funktionierte für mich, führte aber auch zu einem Wettlauf zwischen dem alten JS-Code, den ich ausführen wollte, und dem View-Compiler. AfterViewCheckedAm Ende habe ich verwendet , aber trotzdem, hier ist eine Gegenstimme, um mich in die richtige Richtung zu weisen.
Lukiffer
1
Dies könnte funktionieren, ist jedoch möglicherweise nicht die beste Vorgehensweise. Was besser wäre, wäre, den gesamten externen Code in eine globale, aber gut benannte Funktion zu packen und diese Funktion dann von aufzurufen ngAfterViewInit(). ZB window.MY_APP = {}; MY_APP.init = function () {/*copy all that script.js here*/ }. Dann in Ihrer Komponente, import ...; declare var MY_APP: any; class HomeComponent() { ngAfterViewInit() { MY_APP.init(); } }aber das Endergebnis ist immer noch, dass Sie keine angle2-App haben - Ihre script.js ist im Grunde eine Old-School-Abfrageseite. Sie könnten das meiste davon in NG2-Komponenten verwandeln.
Zlatko
1
Ich stimme dem nicht zu, aber mit dieser Methode kann ich DOM-Elemente erreichen. Wenn ich jedoch versuche, element.css ('height') abzurufen, wird 0px an mich zurückgegeben. Daher kann ich es nicht zum Festlegen von css verwenden.
Explosion
Es hat perfekt für mich funktioniert :) Ich denke, zu diesem Zeitpunkt haben Sie bereits DOM, aber möglicherweise noch nicht alle Quellen geladen, wie Bilder. Also ist es genau so $document.ready().
Affilnost
1
Süß und geschmeidig!
Sam
17

Ich habe mich für diese Lösung entschieden, damit ich meinen benutzerdefinierten js-Code nicht in die andere Komponente als die Funktion jQuery $ .getScript aufnehmen musste .

Hinweis: Hat eine Abhängigkeit von jQuery. Sie benötigen also jQuery- und jQuery-Typisierungen.

Ich habe festgestellt, dass dies ein guter Weg ist, um benutzerdefinierte oder Hersteller-JS-Dateien zu umgehen, für die keine Typisierungen verfügbar sind. TypeScript schreit Sie nicht an, wenn Sie Ihre App starten.

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

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

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

Aktualisieren In meinem Szenario funktionierte das OnInit-Lebenszyklusereignis tatsächlich besser, da das Laden des Skripts nach dem Laden der Ansichten verhindert wurde, was bei ngAfterViewInit der Fall war und die Ansicht vor dem Laden des Skripts falsche Elementpositionen anzeigt.

ngOnInit() {
    $.getScript('../js/mimity.js');
  }
dynamiclynk
quelle
Ich bekomme, Cannot find name '$'.wenn ich versuche, diesem Beispiel zu folgen?
essen-schlafen-Code
3
@ eat-sleep-code Ich denke, du brauchst die jQuery-Eingaben, wie wäre es mit npm install @types/jquery -Deinem Schuss? : D
realappie
4

Um jQuery in Angular zu verwenden, deklarieren Sie $ nur wie folgt: deklarieren Sie var $: any;

Ilir Hushi
quelle
wo legst du das hin
Dan Chase
@ DanChase können Sie es nach den Importen der Bibliotheken in der Klasse platzieren
Ilir Hushi
Schauen Sie sich diesen schönen Artikel an, um jquery mit Angular-Cli auszuschließen: medium.com/@swarnakishore/…
Pavel
3

Die akzeptierte Antwort ist nicht korrekt und es macht keinen Sinn, sie unter Berücksichtigung der Frage zu akzeptieren

ngAfterViewInit wird ausgelöst, wenn das DOM bereit ist

whine ngOnInit wird ausgelöst, wenn die Seitenkomponente erst erstellt wird

phil123456
quelle
1
Versuchen Sie, in Ihrer Antwort nur Ihre Lösung klar zu formulieren. Wenn Sie der Meinung sind, dass eine Antwort nicht korrekt ist, sollten Sie stattdessen diese Frage kommentieren.
Zeeshan Adil
Kein Problem, versuchen Sie einfach, Ihre Antwort klarer zu machen, um mehr Menschen zu helfen. mit einem minimalistischen Codebeispiel.
Zeeshan Adil
-1

In Ihrer main.ts- Datei wird Bootstrap nach DOMContentLoaded so eckig geladen, wenn DOM vollständig geladen ist.

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
quelle