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
    }

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'));
  }
}

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
    }

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');
  }

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


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


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));
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.